From 2b8c32366a2916dfbeac269eea94b2e6ef65f556 Mon Sep 17 00:00:00 2001
From: 张诺 <zhang_12370@163.com>
Date: 星期二, 20 一月 2026 14:40:23 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_New' into dev_New
---
src/views/collaborativeApproval/notificationManagement/summary/index.vue | 8
src/views/financialManagement/accounting/index.vue | 197
src/views/personnelManagement/payrollManagement/components/formDia.vue | 14
src/views/personnelManagement/payrollManagement/index.vue | 1
src/views/personnelManagement/scheduling/index.vue | 10
src/views/qualityManagement/finalInspection/components/inspectionFormDia.vue | 1
src/views/personnelManagement/contractManagement/index.vue | 2
src/views/equipmentManagement/ledger/Form.vue | 74
src/views/collaborativeApproval/sealManagement/index.vue | 4
src/api/procurementManagement/paymentLedger.js | 7
src/views/personnelManagement/contractManagement/components/formDia.vue | 34
src/views/inventoryManagement/receiptManagement/index.vue | 997 +++---
src/views/personnelManagement/employeeRecord/components/RenewContract.vue | 141
src/views/qualityManagement/metricMaintenance/index.vue | 83
src/views/equipmentManagement/ledger/index.vue | 67
src/views/equipmentManagement/upkeep/index.vue | 55
src/views/qualityManagement/processInspection/components/formDia.vue | 180 +
src/views/collaborativeApproval/notificationManagement/meetExamine/index.vue | 8
src/views/procurementManagement/procurementLedger/fileList.vue | 67
src/views/equipmentManagement/repair/Modal/MaintainModal.vue | 115
src/views/reportAnalysis/projectProfit/index.vue | 186
src/views/personnelManagement/employeeRecord/index.vue | 25
src/views/equipmentManagement/repair/Modal/RepairModal.vue | 190 +
src/api/qualityManagement/metricMaintenance.js | 14
src/views/procurementManagement/procurementLedger/index.vue | 3098 ++++++++++++---------
src/views/productionManagement/productionReporting/index.vue | 17
src/views/collaborativeApproval/notificationManagement/meetPublish/index.vue | 8
src/views/qualityManagement/rawMaterialInspection/components/formDia.vue | 109
src/views/productionManagement/productionOrder/index.vue | 2
src/views/inventoryManagement/receiptManagement/components/formDia.vue | 400 ++
src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue | 123
src/views/qualityManagement/rawMaterialInspection/components/inspectionFormDia.vue | 1
src/views/equipmentManagement/upkeep/Form/PlanModal.vue | 188 +
src/views/reportAnalysis/dataDashboard/index.vue | 596 +++
src/views/productionManagement/productionDispatching/components/formDia.vue | 1
src/views/inventoryManagement/receiptManagement/components/formDiaProduct.vue | 302 ++
src/views/salesManagement/salesLedger/index.vue | 116
src/views/collaborativeApproval/notificationManagement/meetApplication/index.vue | 12
src/views/personnelManagement/selfService/index.vue | 12
src/views/qualityManagement/metricBinding/index.vue | 36
src/api/personnelManagement/employeeRecord.js | 27
src/views/qualityManagement/processInspection/components/inspectionFormDia.vue | 1
src/views/collaborativeApproval/enterpriseBook/index.vue | 6
src/views/qualityManagement/finalInspection/components/formDia.vue | 112
src/views/productionManagement/productionCosting/index.vue | 2
src/views/equipmentManagement/repair/index.vue | 48
src/components/PIMTable/PIMTable.vue | 4
src/views/qualityManagement/finalInspection/components/filesDia.vue | 1
/dev/null | 280 -
src/views/personnelManagement/dimission/components/formDia.vue | 181
src/views/lavorissue/ledger/Form.vue | 10
src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue | 55
src/api/personnelManagement/staffLeave.js | 33
src/api/personnelManagement/staffOnJob.js | 11
src/views/equipmentManagement/upkeep/Form/formDia.vue | 304 ++
src/views/personnelManagement/contractManagement/filesDia.vue | 10
src/views/personnelManagement/dimission/index.vue | 58
src/api/financialManagement/accounting.js | 28
src/views/productionManagement/productionReporting/components/formDia.vue | 1
59 files changed, 5,857 insertions(+), 2,816 deletions(-)
diff --git a/src/api/financialManagement/accounting.js b/src/api/financialManagement/accounting.js
new file mode 100644
index 0000000..69bc7cd
--- /dev/null
+++ b/src/api/financialManagement/accounting.js
@@ -0,0 +1,28 @@
+import request from "@/utils/request";
+
+// 鑾峰彇鍥哄畾璧勪骇姹囨�讳俊鎭�
+export const getAccountingTotal = (params) => {
+ return request({
+ url: "/accounting/total",
+ method: "get",
+ params,
+ });
+};
+
+// 鑾峰彇璁惧绫诲瀷鍒嗗竷鏁版嵁锛堥ゼ鍥惧拰鎶樼嚎鍥撅級
+export const getDeviceTypeDistribution = (params) => {
+ return request({
+ url: "/accounting/deviceTypeDistribution",
+ method: "get",
+ params,
+ });
+};
+
+// 鑾峰彇鎶樻棫璁$畻鏁版嵁锛堣〃鏍兼暟鎹級
+export const getCalculateDepreciation = (params) => {
+ return request({
+ url: "/accounting/calculateDepreciation",
+ method: "get",
+ params,
+ });
+};
diff --git a/src/api/personnelManagement/employeeRecord.js b/src/api/personnelManagement/employeeRecord.js
new file mode 100644
index 0000000..a4ad34b
--- /dev/null
+++ b/src/api/personnelManagement/employeeRecord.js
@@ -0,0 +1,27 @@
+import request from '@/utils/request'
+
+// 鏌ヨ鍦ㄨ亴鍛樺伐鍙拌处
+export function staffOnJobListPage(query) {
+ return request({
+ url: '/staff/staffOnJob/listPage',
+ method: 'get',
+ params: query,
+ })
+}
+// 鏌ヨ鍛樺伐鍏ヨ亴淇℃伅
+export function staffOnJobInfo(query) {
+ return request({
+ url: '/staff/staffOnJob/staffNo',
+ method: 'get',
+ params: query,
+ })
+}
+
+// 瀵煎嚭鍚堝悓鍓湰
+export function staffOnJobExportCopy(data) {
+ return request({
+ url: '/staff/staffOnJob/exportCopy',
+ method: 'post',
+ data: data,
+ })
+}
\ No newline at end of file
diff --git a/src/api/personnelManagement/onboarding.js b/src/api/personnelManagement/onboarding.js
deleted file mode 100644
index 39dbf22..0000000
--- a/src/api/personnelManagement/onboarding.js
+++ /dev/null
@@ -1,49 +0,0 @@
-import request from "@/utils/request";
-
-// 鏌ヨ浜哄憳鍏ヨ亴鍒楄〃
-export function staffJoinListPage(query) {
- return request({
- url: "/staff/staffJoinLeaveRecord/listPage",
- method: "get",
- params: query,
- });
-}
-// 鏂板浜哄憳鍏ヨ亴
-export function staffJoinAdd(query) {
- return request({
- url: "/staff/staffJoinLeaveRecord/add",
- method: "post",
- data: query,
- });
-}
-// 淇敼浜哄憳鍏ヨ亴
-export function staffJoinUpdate(query) {
- return request({
- url: "/staff/staffJoinLeaveRecord/update",
- method: "post",
- data: query,
- });
-}
-// 鏌ヨ鍛樺伐鍏ヨ亴淇℃伅
-export function getStaffJoinInfo(query) {
- return request({
- url: "/staff/staffJoinLeaveRecord/" + query,
- method: "get",
- data: query,
- });
-}
-// 鍒犻櫎鍛樺伐
-export function staffJoinDel(query) {
- return request({
- url: "/staff/staffJoinLeaveRecord/del",
- method: "delete",
- data: query,
- });
-}
-
-export function getStaffOnJob() {
- return request({
- url: "/staff/staffOnJob/list",
- method: "get",
- });
-}
diff --git a/src/api/personnelManagement/staffLeave.js b/src/api/personnelManagement/staffLeave.js
new file mode 100644
index 0000000..d675996
--- /dev/null
+++ b/src/api/personnelManagement/staffLeave.js
@@ -0,0 +1,33 @@
+import request from "@/utils/request.js";
+
+export function findStaffLeaveListPage(query) {
+ return request({
+ url: "/staff/staffLeave/listPage",
+ method: "get",
+ params: query,
+ });
+}
+
+export function createStaffLeave(data) {
+ return request({
+ url: "/staff/staffLeave",
+ method: "post",
+ data: data,
+ });
+}
+
+export function updateStaffLeave(id, data) {
+ return request({
+ url: "/staff/staffLeave/" + id,
+ method: "put",
+ data: data,
+ });
+}
+
+export function batchDeleteStaffLeaves(data) {
+ return request({
+ url: "/staff/staffLeave/del",
+ method: "delete",
+ data: data,
+ });
+}
diff --git a/src/api/personnelManagement/staffOnJob.js b/src/api/personnelManagement/staffOnJob.js
index ba26878..7da5469 100644
--- a/src/api/personnelManagement/staffOnJob.js
+++ b/src/api/personnelManagement/staffOnJob.js
@@ -42,4 +42,13 @@
method: "delete",
data: query,
});
-}
\ No newline at end of file
+}
+
+// 缁鍚堝悓
+export function renewContract(id, params) {
+ return request({
+ url: "/staff/staffOnJob/renewContract/" + id,
+ method: "post",
+ data: params,
+ });
+}
diff --git a/src/api/procurementManagement/paymentLedger.js b/src/api/procurementManagement/paymentLedger.js
index a6de8bc..3e20b78 100644
--- a/src/api/procurementManagement/paymentLedger.js
+++ b/src/api/procurementManagement/paymentLedger.js
@@ -4,17 +4,16 @@
// 鍒嗛〉鏌ヨ
export function paymentLedgerList(query) {
return request({
- url: "/purchase/paymentRegistration/supplierNameListPage",
+ url: "/purchase/paymentRegistration/paymentLedgerList",
method: "get",
params: query,
});
}
// 鍒嗛〉鏌ヨ
-export function paymentRecordList(query) {
+export function paymentRecordList(supplierId) {
return request({
- url: "/purchase/paymentRegistration/supplierNameListPageDetails",
+ url: "/purchase/paymentRegistration/getPaymentRecordList/" + supplierId,
method: "get",
- params: query,
});
}
diff --git a/src/api/qualityManagement/metricMaintenance.js b/src/api/qualityManagement/metricMaintenance.js
index 53ca650..1ee9cad 100644
--- a/src/api/qualityManagement/metricMaintenance.js
+++ b/src/api/qualityManagement/metricMaintenance.js
@@ -37,10 +37,11 @@
}
// 鍒犻櫎鎸囨爣鍒楄〃
-export function qualityInspectDetailByProductId(productId) {
+export function qualityInspectDetailByProductId(params) {
return request({
- url: "/qualityTestStandard/product/" + productId,
+ url: "/qualityTestStandard/getQualityTestStandardByProductId",
method: "get",
+ params: params,
});
}
@@ -98,3 +99,12 @@
data: ids,
});
}
+
+// 鏍规嵁鏍囧噯ID鑾峰彇鏍囧噯鍙傛暟
+export function getQualityTestStandardParamByTestStandardId(testStandardId) {
+ return request({
+ url: "/qualityTestStandard/getQualityTestStandardParamByTestStandardId",
+ method: "get",
+ params: { testStandardId },
+ });
+}
diff --git a/src/components/PIMTable/PIMTable.vue b/src/components/PIMTable/PIMTable.vue
index 1480893..dfbc231 100644
--- a/src/components/PIMTable/PIMTable.vue
+++ b/src/components/PIMTable/PIMTable.vue
@@ -130,7 +130,7 @@
</div>
<!-- 鎸夐挳 -->
- <div v-else-if="item.dataType == 'action'">
+ <div v-else-if="item.dataType == 'action'" @click.stop>
<template v-for="(o, key) in item.operation" :key="key">
<el-button
v-show="o.type != 'upload'"
@@ -145,7 +145,7 @@
: o.color,
}"
link
- @click="o.clickFun(scope.row)"
+ @click.stop="o.clickFun(scope.row)"
:key="key"
>
{{ o.name }}
diff --git a/src/views/collaborativeApproval/enterpriseBook/index.vue b/src/views/collaborativeApproval/enterpriseBook/index.vue
index 0b33a32..fa9fa5c 100644
--- a/src/views/collaborativeApproval/enterpriseBook/index.vue
+++ b/src/views/collaborativeApproval/enterpriseBook/index.vue
@@ -295,7 +295,6 @@
getEmployeeDetail
} from '@/api/collaborativeApproval/enterpriseBook.js'
import { getUserProfile } from '@/api/system/user.js'
-import {staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
import {
changeUserStatus,
listUser,
@@ -306,6 +305,7 @@
addUser,
deptTreeSelect,
} from "@/api/system/user";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
// 鏍囩椤电姸鎬�
const activeTab = ref('personal')
@@ -395,7 +395,7 @@
}
//鑾峰彇鍛樺伐鍒楄〃
const getEmployeeList = async () => {
- staffJoinListPage(publicSearch.value).then(res => {
+ staffOnJobListPage(Object.assign({current: -1, size: -1},publicSearch.value)).then(res => {
console.log(res.data.records)
EmployeeList.value = res.data.records
}).catch(err => {})
@@ -403,7 +403,7 @@
// 鑾峰彇鍗曚綅閫氳褰曞垪琛�
const getCompanyContactsList = async () => {
loading.value = true
- staffJoinListPage(companySearch.value).then(res => {
+ staffOnJobListPage(Object.assign({current: -1, size: -1},companySearch.value)).then(res => {
// console.log(res.data.records)
companyContacts.value = res.data.records
}).catch(err => {})
diff --git a/src/views/collaborativeApproval/notificationManagement/meetApplication/index.vue b/src/views/collaborativeApproval/notificationManagement/meetApplication/index.vue
index 7781593..ed2dafa 100644
--- a/src/views/collaborativeApproval/notificationManagement/meetApplication/index.vue
+++ b/src/views/collaborativeApproval/notificationManagement/meetApplication/index.vue
@@ -127,7 +127,7 @@
<el-option
v-for="person in employees"
:key="person.id"
- :label="`${person.staffName} (${person.postJob})`"
+ :label="`${person.staffName} (${person.postName})`"
:value="person.id"
/>
</el-select>
@@ -156,7 +156,7 @@
import {ElMessage} from 'element-plus'
import {Plus, Document, Promotion, Bell} from '@element-plus/icons-vue'
import {getRoomEnum, saveMeetingApplication} from '@/api/collaborativeApproval/meeting.js'
-import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
// 褰撳墠鐢宠绫诲瀷
const currentType = ref('department') // approval: 瀹℃壒娴佺▼, department: 閮ㄩ棬绾�, notification: 閫氱煡鍙戝竷
@@ -302,8 +302,12 @@
getRoomEnum().then(res => {
meetingRooms.value = res.data
})
- getStaffOnJob().then(res => {
- employees.value = res.data.sort((a, b) => a.postJob.localeCompare(b.postJob))
+ staffOnJobListPage({
+ current: -1,
+ size: -1,
+ staffState: 1
+ }).then(res => {
+ employees.value = res.data.records.sort((a, b) => a.postName.localeCompare(b.postName))
})
})
</script>
diff --git a/src/views/collaborativeApproval/notificationManagement/meetExamine/index.vue b/src/views/collaborativeApproval/notificationManagement/meetExamine/index.vue
index 83747a0..157b6b5 100644
--- a/src/views/collaborativeApproval/notificationManagement/meetExamine/index.vue
+++ b/src/views/collaborativeApproval/notificationManagement/meetExamine/index.vue
@@ -188,8 +188,8 @@
import {ElMessage, ElMessageBox} from 'element-plus'
import Pagination from '@/components/Pagination/index.vue'
import {getRoomEnum, getExamineList,saveMeetingApplication} from '@/api/collaborativeApproval/meeting.js'
-import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js";
import dayjs from "dayjs";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
// 鏁版嵁鍒楄〃鍔犺浇鐘舵��
const loading = ref(false)
@@ -240,7 +240,7 @@
it.participants = staffList.value.filter(staff => staffs.some(id=>id === staff.id)).map(staff => {
return {
id: staff.id,
- name: `${staff.staffName}(${staff.postJob})`
+ name: `${staff.staffName}(${staff.postName})`
}
})
@@ -342,9 +342,9 @@
// 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
onMounted(async () => {
- const [resp1, resp2]= await Promise.all([getRoomEnum(), getStaffOnJob()])
+ const [resp1, resp2]= await Promise.all([getRoomEnum(), staffOnJobListPage({current: -1, size: -1, staffState: 1})])
roomEnum.value = resp1.data
- staffList.value = resp2.data
+ staffList.value = resp2.data.records
await getList()
})
diff --git a/src/views/collaborativeApproval/notificationManagement/meetPublish/index.vue b/src/views/collaborativeApproval/notificationManagement/meetPublish/index.vue
index 2351293..a85de7f 100644
--- a/src/views/collaborativeApproval/notificationManagement/meetPublish/index.vue
+++ b/src/views/collaborativeApproval/notificationManagement/meetPublish/index.vue
@@ -186,8 +186,8 @@
import {ElMessage, ElMessageBox} from 'element-plus'
import Pagination from '@/components/Pagination/index.vue'
import {getRoomEnum, getMeetingPublish,saveMeetingApplication} from '@/api/collaborativeApproval/meeting.js'
-import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js";
import dayjs from "dayjs";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
// 鏁版嵁鍒楄〃鍔犺浇鐘舵��
const loading = ref(false)
@@ -239,7 +239,7 @@
it.participants = staffList.value.filter(staff => staffs.some(id=>id === staff.id)).map(staff => {
return {
id: staff.id,
- name: `${staff.staffName}(${staff.postJob})`
+ name: `${staff.staffName}(${staff.postName})`
}
})
@@ -340,9 +340,9 @@
// 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
onMounted(async () => {
- const [resp1, resp2]= await Promise.all([getRoomEnum(), getStaffOnJob()])
+ const [resp1, resp2]= await Promise.all([getRoomEnum(), staffOnJobListPage({current: -1, size: -1, staffState: 1})])
roomEnum.value = resp1.data
- staffList.value = resp2.data
+ staffList.value = resp2.data.records
await getList()
})
diff --git a/src/views/collaborativeApproval/notificationManagement/summary/index.vue b/src/views/collaborativeApproval/notificationManagement/summary/index.vue
index a00316d..f94e548 100644
--- a/src/views/collaborativeApproval/notificationManagement/summary/index.vue
+++ b/src/views/collaborativeApproval/notificationManagement/summary/index.vue
@@ -160,8 +160,8 @@
import Pagination from '@/components/Pagination/index.vue'
import Editor from '@/components/Editor/index.vue'
import { getRoomEnum, getMeetingPublish ,getMeetingMinutesByMeetingId,saveMeetingMinutes} from '@/api/collaborativeApproval/meeting.js'
-import { getStaffOnJob } from "@/api/personnelManagement/onboarding.js"
import dayjs from "dayjs"
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
// 鏁版嵁鍒楄〃鍔犺浇鐘舵��
const loading = ref(false)
@@ -214,7 +214,7 @@
it.participants = staffList.value.filter(staff => staffs.some(id => id === staff.id)).map(staff => {
return {
id: staff.id,
- name: `${staff.staffName}(${staff.postJob})`
+ name: `${staff.staffName}(${staff.postName})`
}
})
@@ -337,9 +337,9 @@
// 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
onMounted(async () => {
- const [resp1, resp2] = await Promise.all([getRoomEnum(), getStaffOnJob()])
+ const [resp1, resp2] = await Promise.all([getRoomEnum(), staffOnJobListPage({current: -1, size: -1, staffState: 1})])
roomEnum.value = resp1.data
- staffList.value = resp2.data
+ staffList.value = resp2.data.records
await getList()
})
diff --git a/src/views/collaborativeApproval/sealManagement/index.vue b/src/views/collaborativeApproval/sealManagement/index.vue
index 8e0d054..9f70a55 100644
--- a/src/views/collaborativeApproval/sealManagement/index.vue
+++ b/src/views/collaborativeApproval/sealManagement/index.vue
@@ -261,9 +261,9 @@
import { listSealApplication, addSealApplication, updateSealApplication,listRuleManagement,addRuleManagement,updateRuleManagement,delRuleManagement,getReadingStatusByRuleId,getReadingStatusList,addReadingStatus,updateReadingStatus } from '@/api/collaborativeApproval/sealManagement.js'
import { el } from 'element-plus/es/locales.mjs'
import { getUserProfile, userListNoPageByTenantId } from '@/api/system/user.js'
-import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
import useUserStore from '@/store/modules/user'
import { userLoginFacotryList } from "@/api/system/user.js"
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
// 鍝嶅簲寮忔暟鎹�
const currentUser = ref(null)
@@ -583,7 +583,7 @@
currentUser.value = res.data.userName
}
})
- staffJoinListPage({staffState: 1, ...page}).then(res => {
+ staffOnJobListPage({staffState: 1, ...page}).then(res => {
tableLoading.value = false;
// tableData.value = res.data.records
// //绛涢�夊嚭鍜宑urrentUser鍚屽悕鐨勪汉鍛�
diff --git a/src/views/equipmentManagement/ledger/Form.vue b/src/views/equipmentManagement/ledger/Form.vue
index d14f4ff..f85a7fa 100644
--- a/src/views/equipmentManagement/ledger/Form.vue
+++ b/src/views/equipmentManagement/ledger/Form.vue
@@ -1,5 +1,5 @@
<template>
- <el-form :model="form" label-width="100px" :rules="formRules" ref="formRef">
+ <el-form :model="form" label-width="120px" :rules="formRules" ref="formRef">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="璁惧鍚嶇О" prop="deviceName">
@@ -14,6 +14,27 @@
<el-col :span="12">
<el-form-item label="璁惧鍝佺墝" prop="deviceBrand">
<el-input v-model="form.deviceBrand" placeholder="璇疯緭鍏ヨ澶囧搧鐗�" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="璁惧绫诲瀷" prop="type">
+ <el-select
+ v-model="form.type"
+ placeholder="璇烽�夋嫨鎴栬緭鍏ヨ澶囩被鍨�"
+ clearable
+ filterable
+ allow-create
+ default-first-option
+ style="width: 100%"
+ @change="handleDeviceTypeChange"
+ >
+ <el-option
+ v-for="item in deviceTypeOptions"
+ :key="item"
+ :label="item"
+ :value="item"
+ />
+ </el-select>
</el-form-item>
</el-col>
<el-col :span="12">
@@ -32,8 +53,19 @@
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="鍚敤鎶樻棫" prop="enableDepreciation">
- <el-switch v-model="form.enableDepreciation" :active-value="true" :inactive-value="false" />
+ <el-form-item label="鍚敤鎶樻棫" prop="isDepr">
+ <el-switch v-model="form.isDepr" :active-value="1" :inactive-value="2" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12" v-if="form.isDepr === 1">
+ <el-form-item label="姣忓勾鎶樻棫閲戦" prop="annualDepreciationAmount">
+ <el-input-number
+ :step="0.01"
+ :min="0"
+ style="width: 100%"
+ v-model="form.annualDepreciationAmount"
+ placeholder="璇疯緭鍏ユ瘡骞存姌鏃ч噾棰�"
+ />
</el-form-item>
</el-col>
<el-col :span="12">
@@ -149,24 +181,47 @@
});
const formRef = ref(null);
const operationType = ref('');
+// 璁惧绫诲瀷鍥哄畾閫夐」
+const deviceTypeOptions = ref([
+ '鐢熶骇璁惧',
+ '鍔炲叕璁惧',
+ '妫�娴嬭澶�',
+ '杩愯緭璁惧',
+ '鍏朵粬璁惧'
+]);
const formRules = {
deviceName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
deviceModel: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
+ type: [{ required: true, trigger: "change", message: "璇烽�夋嫨鎴栬緭鍏ヨ澶囩被鍨�" }],
supplierName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
unit: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
number: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
taxIncludingPriceUnit: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
taxRate: [{ required: true, trigger: "change", message: "璇疯緭鍏�" }],
planRuntimeTime: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
+ annualDepreciationAmount: [
+ {
+ validator: (rule, value, callback) => {
+ if (form.isDepr === 1 && (value === undefined || value === null || value === '')) {
+ callback(new Error('鍚敤鎶樻棫鏃讹紝璇疯緭鍏ユ瘡骞存姌鏃ч噾棰�'));
+ } else {
+ callback();
+ }
+ },
+ trigger: "blur"
+ }
+ ],
}
const { form, resetForm } = useFormData({
deviceName: undefined, // 璁惧鍚嶇О
deviceModel: undefined, // 瑙勬牸鍨嬪彿
deviceBrand: undefined, // 璁惧鍝佺墝
+ type: undefined, // 璁惧绫诲瀷
supplierName: undefined, // 渚涘簲鍟�
storageLocation: undefined, // 瀛樻斁浣嶇疆
- enableDepreciation: false, // 鏄惁鍚敤鎶樻棫
+ isDepr: 2, // 鏄惁鍚敤鎶樻棫 1-鏄� 2-鍚�
+ annualDepreciationAmount: undefined, // 姣忓勾鎶樻棫閲戦
unit: undefined, // 鍗曚綅
number: 1, // 鏁伴噺
taxIncludingPriceUnit: undefined, // 鍚◣鍗曚环
@@ -187,9 +242,11 @@
form.deviceName = data.deviceName;
form.deviceModel = data.deviceModel;
form.deviceBrand = data.deviceBrand;
+ form.type = data.type;
form.supplierName = data.supplierName;
form.storageLocation = data.storageLocation;
- form.enableDepreciation = data.enableDepreciation;
+ form.isDepr = data.isDepr;
+ form.annualDepreciationAmount = data.annualDepreciationAmount;
form.unit = data.unit;
form.number = 1;
form.taxIncludingPriceUnit = data.taxIncludingPriceUnit;
@@ -200,6 +257,13 @@
}
};
+const handleDeviceTypeChange = (value) => {
+ // 濡傛灉杈撳叆鐨勬柊鍊间笉鍦ㄥ浐瀹氶�夐」涓紝鍒欐坊鍔犲埌閫夐」鍒楄〃
+ if (value && !deviceTypeOptions.value.includes(value)) {
+ deviceTypeOptions.value.push(value);
+ }
+};
+
const mathNum = () => {
if (!form.taxIncludingPriceUnit) {
ElMessage.error("璇疯緭鍏ュ崟浠�");
diff --git a/src/views/equipmentManagement/ledger/index.vue b/src/views/equipmentManagement/ledger/index.vue
index 8cdbf32..62f0c6a 100644
--- a/src/views/equipmentManagement/ledger/index.vue
+++ b/src/views/equipmentManagement/ledger/index.vue
@@ -7,7 +7,6 @@
style="width: 240px"
placeholder="璇疯緭鍏ヨ澶囧悕绉�"
clearable
- :prefix-icon="Search"
@change="getTableData"
/>
</el-form-item>
@@ -17,7 +16,6 @@
style="width: 240px"
placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
clearable
- :prefix-icon="Search"
@change="getTableData"
/>
</el-form-item>
@@ -27,17 +25,6 @@
style="width: 240px"
placeholder="璇疯緭鍏ヤ緵搴斿晢"
clearable
- :prefix-icon="Search"
- @change="getTableData"
- />
- </el-form-item>
- <el-form-item label="鍗曚綅">
- <el-input
- v-model="filters.unit"
- style="width: 240px"
- placeholder="璇疯緭鍏ュ崟浣�"
- clearable
- :prefix-icon="Search"
@change="getTableData"
/>
</el-form-item>
@@ -130,81 +117,53 @@
deviceName: undefined,
deviceModel: undefined,
supplierName: undefined,
- unit: undefined,
entryDateStart: undefined,
entryDateEnd: undefined,
},
[
{
label: "璁惧鍚嶇О",
- align: "center",
prop: "deviceName",
},
{
label: "瑙勬牸鍨嬪彿",
- align: "center",
prop: "deviceModel",
},
{
label: "璁惧鍝佺墝",
- align: "center",
prop: "deviceBrand",
},
{
+ label: "璁惧绫诲瀷",
+ prop: "type",
+ },
+ {
label: "渚涘簲鍟�",
- align: "center",
prop: "supplierName",
},
{
- label: "鍗曚綅",
- align: "center",
- prop: "unit",
- },
- {
label: "瀛樻斁浣嶇疆",
- align: "center",
prop: "storageLocation",
},
{
label: "鏁伴噺",
- align: "center",
prop: "number",
},
{
- label: "鍚◣鍗曚环",
- align: "center",
- prop: "taxIncludingPriceUnit",
- },
- {
- label: "鍚◣鎬讳环",
- align: "center",
- prop: "taxIncludingPriceTotal",
- },
- {
- label: "绋庣巼",
- align: "center",
- prop: "taxRate",
- },
- {
- label: "涓嶅惈绋庢�讳环",
- align: "center",
- prop: "unTaxIncludingPriceTotal",
- },
- {
- label: "鍚敤鎶樻棫",
- align: "center",
- prop: "enableDepreciation",
- formatData: (v) => (v ? "鏄�" : "鍚�"),
- },
- {
label: "褰曞叆浜�",
- align: "center",
prop: "createUser",
},
{
label: "褰曞叆鏃ユ湡",
- align: "center",
prop: "createTime",
+ formatData: (v) => {
+ if (!v) return '';
+ // 濡傛灉鍖呭惈鏃跺垎绉掞紝鍙彇鏃ユ湡閮ㄥ垎
+ if (v.includes(' ')) {
+ return v.split(' ')[0];
+ }
+ return v;
+ },
},
{
dataType: "action",
@@ -215,14 +174,12 @@
operation: [
{
name: "缂栬緫",
- type: "text",
clickFun: (row) => {
edit(row.id)
},
},
{
name: "鐢熸垚浜岀淮鐮�",
- type: "text",
clickFun: (row) => {
showQRCode(row)
},
diff --git a/src/views/equipmentManagement/repair/Form/MaintainForm.vue b/src/views/equipmentManagement/repair/Form/MaintainForm.vue
deleted file mode 100644
index 2a64d3f..0000000
--- a/src/views/equipmentManagement/repair/Form/MaintainForm.vue
+++ /dev/null
@@ -1,66 +0,0 @@
-<template>
- <el-form :model="form" label-width="80px">
- <el-form-item label="缁翠慨浜�">
- <el-input v-model="form.maintenanceName" placeholder="璇疯緭鍏ョ淮淇汉" />
- </el-form-item>
- <el-form-item label="缁翠慨缁撴灉">
- <el-input v-model="form.maintenanceResult" placeholder="璇疯緭鍏ョ淮淇粨鏋�" />
- </el-form-item>
- <el-form-item label="鎶ヤ慨鐘舵��">
- <el-select v-model="form.status">
- <el-option label="寰呮姤淇�" :value="0"></el-option>
- <el-option label="瀹岀粨" :value="1"></el-option>
- <el-option label="澶辫触" :value="2"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="缁翠慨鏃ユ湡">
- <el-date-picker
- v-model="form.maintenanceTime"
- placeholder="璇烽�夋嫨缁翠慨鏃ユ湡"
- format="YYYY-MM-DD HH:mm:ss"
- value-format="YYYY-MM-DD HH:mm:ss"
- type="datetime"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import useUserStore from "@/store/modules/user";
-import dayjs from "dayjs";
-
-defineOptions({
- name: "璁惧缁翠慨琛ㄥ崟",
-});
-
-const userStore = useUserStore();
-const { form, resetForm } = useFormData({
- maintenanceName: undefined, // 缁翠慨鍚嶇О
- maintenanceResult: undefined, // 缁翠慨缁撴灉
- maintenanceTime: undefined, // 缁翠慨鏃ユ湡
- status: 0,
-});
-
-const setForm = (data) => {
- form.maintenanceName = data.maintenanceName ?? userStore.nickName;
- form.maintenanceResult = data.maintenanceResult;
- form.maintenanceTime =
- dayjs(data.maintenanceTime).format("YYYY-MM-DD HH:mm:ss") ??
- dayjs().format("YYYY-MM-DD HH:mm:ss");
-};
-
-const getForm = () => {
- return form;
-};
-
-defineExpose({
- getForm,
- setForm,
- resetForm,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/repair/Form/RepairForm.vue b/src/views/equipmentManagement/repair/Form/RepairForm.vue
deleted file mode 100644
index 6697906..0000000
--- a/src/views/equipmentManagement/repair/Form/RepairForm.vue
+++ /dev/null
@@ -1,131 +0,0 @@
-<template>
- <el-form :model="form" label-width="100px">
- <el-row>
- <el-col :span="12">
- <el-form-item label="璁惧鍚嶇О">
- <el-select v-model="form.deviceLedgerId" @change="setDeviceModel" filterable>
- <el-option
- v-for="(item, index) in deviceOptions"
- :key="index"
- :label="item.deviceName"
- :value="item.id"
- ></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="瑙勬牸鍨嬪彿">
- <el-input
- v-model="form.deviceModel"
- placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
- disabled
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鎶ヤ慨鏃ユ湡">
- <el-date-picker
- v-model="form.repairTime"
- placeholder="璇烽�夋嫨鎶ヤ慨鏃ユ湡"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- type="date"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鎶ヤ慨浜�">
- <el-input v-model="form.repairName" placeholder="璇疯緭鍏ユ姤淇汉" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row v-if="id">
- <el-col :span="12">
- <el-form-item label="鎶ヤ慨鐘舵��">
- <el-select v-model="form.status">
- <el-option label="寰呯淮淇�" :value="0"></el-option>
- <el-option label="瀹岀粨" :value="1"></el-option>
- <el-option label="澶辫触" :value="2"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-col :span="24">
- <el-form-item label="鏁呴殰鐜拌薄">
- <el-input
- v-model="form.remark"
- :rows="2"
- type="textarea"
- placeholder="璇疯緭鍏ユ晠闅滅幇璞�"
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
-</template>
-
-<script setup>
-import dayjs from "dayjs";
-import useFormData from "@/hooks/useFormData";
-import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
-import useUserStore from "@/store/modules/user";
-
-const { id } = defineProps(["id"])
-
-defineOptions({
- name: "璁惧鎶ヤ慨琛ㄥ崟",
-});
-
-const userStore = useUserStore();
-const deviceOptions = ref([]);
-
-const loadDeviceName = async () => {
- const { data } = await getDeviceLedger();
- deviceOptions.value = data;
-};
-
-const { form, resetForm } = useFormData({
- deviceLedgerId: undefined, // 璁惧Id
- deviceName: undefined, // 璁惧鍚嶇О
- deviceModel: undefined, // 瑙勬牸鍨嬪彿
- repairTime: dayjs().format("YYYY-MM-DD"), // 鎶ヤ慨鏃ユ湡锛岄粯璁ゅ綋澶�
- repairName: userStore.nickName, // 鎶ヤ慨浜�
- remark: undefined, // 鏁呴殰鐜拌薄
- status: 0, // 鎶ヤ慨鐘舵��
-});
-
-const setDeviceModel = (id) => {
- const option = deviceOptions.value.find((item) => item.id === id);
- form.deviceModel = option.deviceModel;
-};
-
-const getForm = () => {
- return form;
-};
-
-const setForm = (data) => {
- form.deviceLedgerId = data.deviceLedgerId;
- form.deviceName = data.deviceName;
- form.deviceModel = data.deviceModel;
- form.repairTime = data.repairTime;
- form.repairName = data.repairName;
- form.remark = data.remark;
- form.status = data.status;
-};
-
-// onMounted(() => {
-// loadDeviceName();
-// });
-
-defineExpose({
- loadDeviceName,
- resetForm,
- getForm,
- setForm,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/repair/Modal/MaintainModal.vue b/src/views/equipmentManagement/repair/Modal/MaintainModal.vue
index a578a58..496b072 100644
--- a/src/views/equipmentManagement/repair/Modal/MaintainModal.vue
+++ b/src/views/equipmentManagement/repair/Modal/MaintainModal.vue
@@ -1,53 +1,108 @@
<template>
- <el-dialog v-model="visible" :title="modalOptions.title" direction="ltr" draggable>
- <MaintainForm ref="maintainFormRef" />
- <template #footer>
- <el-button type="primary" @click="sendForm" :loading="loading">
- {{ modalOptions.confirmText }}
- </el-button>
- <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
- </template>
- </el-dialog>
+ <FormDialog
+ v-model="visible"
+ :title="'璁惧缁翠慨'"
+ width="500px"
+ @confirm="sendForm"
+ @cancel="handleCancel"
+ @close="handleClose"
+ >
+ <el-form :model="form" label-width="80px">
+ <el-form-item label="缁翠慨浜�">
+ <el-input v-model="form.maintenanceName" placeholder="璇疯緭鍏ョ淮淇汉" />
+ </el-form-item>
+ <el-form-item label="缁翠慨缁撴灉">
+ <el-input v-model="form.maintenanceResult" placeholder="璇疯緭鍏ョ淮淇粨鏋�" />
+ </el-form-item>
+ <el-form-item label="缁翠慨鐘舵��">
+ <el-select v-model="form.status">
+ <el-option label="寰呮姤淇�" :value="0"></el-option>
+ <el-option label="瀹岀粨" :value="1"></el-option>
+ <el-option label="澶辫触" :value="2"></el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item label="缁翠慨鏃ユ湡">
+ <el-date-picker
+ v-model="form.maintenanceTime"
+ placeholder="璇烽�夋嫨缁翠慨鏃ユ湡"
+ format="YYYY-MM-DD HH:mm:ss"
+ value-format="YYYY-MM-DD HH:mm:ss"
+ type="datetime"
+ clearable
+ style="width: 100%"
+ />
+ </el-form-item>
+ </el-form>
+ </FormDialog>
</template>
<script setup>
-import { useModal } from "@/hooks/useModal";
-import MaintainForm from "../Form/MaintainForm.vue";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
import { addMaintain } from "@/api/equipmentManagement/repair";
+import useFormData from "@/hooks/useFormData";
+import useUserStore from "@/store/modules/user";
+import dayjs from "dayjs";
+import { ElMessage } from "element-plus";
defineOptions({
name: "缁翠慨妯℃�佹",
});
-const maintainFormRef = ref();
const emits = defineEmits(["ok"]);
-const {
- id,
- visible,
- loading,
- openModal,
- modalOptions,
- handleConfirm,
- closeModal,
-} = useModal({ title: "璁惧缁翠慨" });
+// 淇濆瓨鎶ヤ慨璁板綍鐨刬d
+const repairId = ref();
+const visible = ref(false);
+const loading = ref(false);
+
+const userStore = useUserStore();
+const { form, resetForm } = useFormData({
+ maintenanceName: undefined, // 缁翠慨鍚嶇О
+ maintenanceResult: undefined, // 缁翠慨缁撴灉
+ maintenanceTime: undefined, // 缁翠慨鏃ユ湡
+ status: 0,
+});
+
+const setForm = (data) => {
+ form.maintenanceName = data.maintenanceName ?? userStore.nickName;
+ form.maintenanceResult = data.maintenanceResult;
+ form.maintenanceTime =
+ data.maintenanceTime
+ ? dayjs(data.maintenanceTime).format("YYYY-MM-DD HH:mm:ss")
+ : dayjs().format("YYYY-MM-DD HH:mm:ss");
+ form.status = 1; // 榛樿鐘舵�佷负瀹岀粨
+};
const sendForm = async () => {
loading.value = true;
- const form = await maintainFormRef.value.getForm();
- const { code } = await addMaintain({ id: id.value, ...form });
- if (code == 200) {
- emits("ok");
- maintainFormRef.value.resetForm();
- closeModal();
+ try {
+ const { code } = await addMaintain({ id: repairId.value, ...form });
+ if (code == 200) {
+ ElMessage.success("缁翠慨鎴愬姛");
+ emits("ok");
+ resetForm();
+ visible.value = false;
+ }
+ } finally {
+ loading.value = false;
}
- loading.value = false;
+};
+
+const handleCancel = () => {
+ resetForm();
+ visible.value = false;
+};
+
+const handleClose = () => {
+ resetForm();
+ visible.value = false;
};
const open = async (id, row) => {
- openModal(id);
+ repairId.value = id; // 淇濆瓨鎶ヤ慨璁板綍鐨刬d
+ visible.value = true;
await nextTick();
- maintainFormRef.value.setForm(row);
+ setForm(row);
};
defineExpose({
diff --git a/src/views/equipmentManagement/repair/Modal/RepairModal.vue b/src/views/equipmentManagement/repair/Modal/RepairModal.vue
index c21b47a..1aa82ec 100644
--- a/src/views/equipmentManagement/repair/Modal/RepairModal.vue
+++ b/src/views/equipmentManagement/repair/Modal/RepairModal.vue
@@ -1,24 +1,93 @@
<template>
- <el-dialog v-model="visible" :title="modalOptions.title" @close="close" draggable>
- <RepairForm ref="repairFormRef" :id="id" />
- <template #footer>
- <el-button type="primary" @click="sendForm" :loading="loading">
- {{ modalOptions.confirmText }}
- </el-button>
- <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
- </template>
- </el-dialog>
+ <FormDialog
+ v-model="visible"
+ :title="id ? '缂栬緫璁惧鎶ヤ慨' : '鏂板璁惧鎶ヤ慨'"
+ width="800px"
+ @confirm="sendForm"
+ @cancel="handleCancel"
+ @close="handleClose"
+ >
+ <el-form :model="form" label-width="100px">
+ <el-row>
+ <el-col :span="12">
+ <el-form-item label="璁惧鍚嶇О">
+ <el-select v-model="form.deviceLedgerId" @change="setDeviceModel" filterable>
+ <el-option
+ v-for="(item, index) in deviceOptions"
+ :key="index"
+ :label="item.deviceName"
+ :value="item.id"
+ ></el-option>
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="瑙勬牸鍨嬪彿">
+ <el-input
+ v-model="form.deviceModel"
+ placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
+ disabled
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鎶ヤ慨鏃ユ湡">
+ <el-date-picker
+ v-model="form.repairTime"
+ placeholder="璇烽�夋嫨鎶ヤ慨鏃ユ湡"
+ format="YYYY-MM-DD"
+ value-format="YYYY-MM-DD"
+ type="date"
+ clearable
+ style="width: 100%"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鎶ヤ慨浜�">
+ <el-input v-model="form.repairName" placeholder="璇疯緭鍏ユ姤淇汉" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row v-if="id">
+ <el-col :span="12">
+ <el-form-item label="鎶ヤ慨鐘舵��">
+ <el-select v-model="form.status">
+ <el-option label="寰呯淮淇�" :value="0"></el-option>
+ <el-option label="瀹岀粨" :value="1"></el-option>
+ <el-option label="澶辫触" :value="2"></el-option>
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row>
+ <el-col :span="24">
+ <el-form-item label="鏁呴殰鐜拌薄">
+ <el-input
+ v-model="form.remark"
+ :rows="2"
+ type="textarea"
+ placeholder="璇疯緭鍏ユ晠闅滅幇璞�"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ </FormDialog>
</template>
<script setup>
-import { useModal } from "@/hooks/useModal";
-import RepairForm from "../Form/RepairForm.vue";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
import {
addRepair,
editRepair,
getRepairById,
} from "@/api/equipmentManagement/repair";
import { ElMessage } from "element-plus";
+import dayjs from "dayjs";
+import useFormData from "@/hooks/useFormData";
+import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
+import useUserStore from "@/store/modules/user";
defineOptions({
name: "璁惧鎶ヤ慨寮圭獥",
@@ -26,48 +95,83 @@
const emits = defineEmits(["ok"]);
-const repairFormRef = ref();
-const {
- id,
- visible,
- loading,
- openModal,
- modalOptions,
- handleConfirm,
- closeModal,
-} = useModal({ title: "璁惧鎶ヤ慨" });
+const id = ref();
+const visible = ref(false);
+const loading = ref(false);
+
+const userStore = useUserStore();
+const deviceOptions = ref([]);
+
+const loadDeviceName = async () => {
+ const { data } = await getDeviceLedger();
+ deviceOptions.value = data;
+};
+
+const { form, resetForm } = useFormData({
+ deviceLedgerId: undefined, // 璁惧Id
+ deviceName: undefined, // 璁惧鍚嶇О
+ deviceModel: undefined, // 瑙勬牸鍨嬪彿
+ repairTime: dayjs().format("YYYY-MM-DD"), // 鎶ヤ慨鏃ユ湡锛岄粯璁ゅ綋澶�
+ repairName: userStore.nickName, // 鎶ヤ慨浜�
+ remark: undefined, // 鏁呴殰鐜拌薄
+ status: 0, // 鎶ヤ慨鐘舵��
+});
+
+const setDeviceModel = (deviceId) => {
+ const option = deviceOptions.value.find((item) => item.id === deviceId);
+ form.deviceModel = option.deviceModel;
+};
+
+const setForm = (data) => {
+ form.deviceLedgerId = data.deviceLedgerId;
+ form.deviceName = data.deviceName;
+ form.deviceModel = data.deviceModel;
+ form.repairTime = data.repairTime;
+ form.repairName = data.repairName;
+ form.remark = data.remark;
+ form.status = data.status;
+};
const sendForm = async () => {
loading.value = true;
- const form = await repairFormRef.value.getForm();
- const { code } = id.value
- ? await editRepair({ id: unref(id), ...form })
- : await addRepair(form);
- if (code == 200) {
- ElMessage.success(`${id ? "缂栬緫" : "鏂板"}鎶ヤ慨鎴愬姛`);
- closeModal();
- emits("ok");
+ try {
+ const { code } = id.value
+ ? await editRepair({ id: unref(id), ...form })
+ : await addRepair(form);
+ if (code == 200) {
+ ElMessage.success(`${id.value ? "缂栬緫" : "鏂板"}鎶ヤ慨鎴愬姛`);
+ visible.value = false;
+ emits("ok");
+ }
+ } finally {
+ loading.value = false;
}
- loading.value = false;
+};
+
+const handleCancel = () => {
+ resetForm();
+ visible.value = false;
+};
+
+const handleClose = () => {
+ resetForm();
+ visible.value = false;
};
const openAdd = async () => {
- openModal();
+ id.value = undefined;
+ visible.value = true;
await nextTick();
- await repairFormRef.value.loadDeviceName();
+ await loadDeviceName();
};
-const openEdit = async (id) => {
- const { data } = await getRepairById(id);
- openModal(id);
+const openEdit = async (editId) => {
+ const { data } = await getRepairById(editId);
+ id.value = editId;
+ visible.value = true;
await nextTick();
- await repairFormRef.value.loadDeviceName();
- await repairFormRef.value.setForm(data);
-};
-
-const close = () => {
- repairFormRef.value.resetForm();
- closeModal();
+ await loadDeviceName();
+ setForm(data);
};
defineExpose({
@@ -75,3 +179,5 @@
openEdit,
});
</script>
+
+<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/repair/index.vue b/src/views/equipmentManagement/repair/index.vue
index 08cbcc2..477e880 100644
--- a/src/views/equipmentManagement/repair/index.vue
+++ b/src/views/equipmentManagement/repair/index.vue
@@ -68,14 +68,6 @@
<div class="actions">
<el-text class="mx-1" size="large">璁惧鎶ヤ慨</el-text>
<div>
- <el-button
- type="primary"
- icon="Plus"
- :disabled="multipleList.length !== 1"
- @click="addMaintain"
- >
- 鏂板缁翠慨
- </el-button>
<el-button type="success" icon="Van" @click="addRepair">
鏂板鎶ヤ慨
</el-button>
@@ -85,7 +77,7 @@
<el-button
type="danger"
icon="Delete"
- :disabled="multipleList.length <= 0"
+ :disabled="multipleList.length <= 0 || hasFinishedStatus"
@click="delRepairByIds(multipleList.map((item) => item.id))"
>
鎵归噺鍒犻櫎
@@ -113,16 +105,24 @@
<template #operation="{ row }">
<el-button
type="primary"
- text
- icon="editPen"
+ link
+ :disabled="row.status === 1"
@click="editRepair(row.id)"
>
缂栬緫
</el-button>
<el-button
+ type="success"
+ link
+ :disabled="row.status === 1"
+ @click="addMaintain(row)"
+ >
+ 缁翠慨
+ </el-button>
+ <el-button
type="danger"
- text
- icon="delete"
+ link
+ :disabled="row.status === 1"
@click="delRepairByIds(row.id)"
>
鍒犻櫎
@@ -138,7 +138,7 @@
<script setup>
import { usePaginationApi } from "@/hooks/usePaginationApi";
import { getRepairPage, delRepair } from "@/api/equipmentManagement/repair";
-import { onMounted, getCurrentInstance } from "vue";
+import { onMounted, getCurrentInstance, computed } from "vue";
import RepairModal from "./Modal/RepairModal.vue";
import { ElMessageBox, ElMessage } from "element-plus";
import dayjs from "dayjs";
@@ -258,6 +258,11 @@
multipleList.value = selectionList;
};
+// 妫�鏌ラ�変腑鐨勮褰曚腑鏄惁鏈夊畬缁撶姸鎬佺殑
+const hasFinishedStatus = computed(() => {
+ return multipleList.value.some(item => item.status === 1)
+})
+
// 鏂板鎶ヤ慨
const addRepair = () => {
repairModalRef.value.openAdd();
@@ -269,8 +274,7 @@
};
// 鏂板缁翠慨
-const addMaintain = () => {
- const row = multipleList.value[0];
+const addMaintain = (row) => {
maintainModalRef.value.open(row.id, row);
};
@@ -282,6 +286,18 @@
// 鍗曡鍒犻櫎
const delRepairByIds = async (ids) => {
+ // 妫�鏌ユ槸鍚︽湁瀹岀粨鐘舵�佺殑璁板綍
+ const idsArray = Array.isArray(ids) ? ids : [ids];
+ const hasFinished = idsArray.some(id => {
+ const record = dataList.value.find(item => item.id === id);
+ return record && record.status === 1;
+ });
+
+ if (hasFinished) {
+ ElMessage.warning('涓嶈兘鍒犻櫎鐘舵�佷负瀹岀粨鐨勮褰�');
+ return;
+ }
+
ElMessageBox.confirm("纭鍒犻櫎鎶ヤ慨鏁版嵁, 姝ゆ搷浣滀笉鍙��?", "璀﹀憡", {
confirmButtonText: "纭畾",
cancelButtonText: "鍙栨秷",
diff --git a/src/views/equipmentManagement/upkeep/Form/MaintenanceForm.vue b/src/views/equipmentManagement/upkeep/Form/MaintenanceForm.vue
deleted file mode 100644
index 3aa0867..0000000
--- a/src/views/equipmentManagement/upkeep/Form/MaintenanceForm.vue
+++ /dev/null
@@ -1,77 +0,0 @@
-<template>
- <el-form :model="form" label-width="100px">
- <el-form-item label="瀹為檯淇濆吇浜�">
- <el-input
- v-model="form.maintenanceActuallyName"
- placeholder="璇疯緭鍏ュ疄闄呬繚鍏讳汉"
- ></el-input>
- </el-form-item>
- <el-form-item label="瀹為檯淇濆吇鏃ユ湡">
- <el-date-picker
- v-model="form.maintenanceActuallyTime"
- placeholder="璇烽�夋嫨瀹為檯淇濆吇鏃ユ湡"
- format="YYYY-MM-DD HH:mm:ss"
- value-format="YYYY-MM-DD HH:mm:ss"
- type="datetime"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- <el-form-item label="淇濆吇鐘舵��">
- <el-select v-model="form.status">
- <el-option label="寰呬繚鍏�" :value="0"></el-option>
- <el-option label="瀹岀粨" :value="1"></el-option>
- <el-option label="澶辫触" :value="2"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="淇濆吇缁撴灉">
- <!-- <el-select v-model="form.maintenanceResult" placeholder="璇烽�夋嫨淇濆吇缁撴灉">
- <el-option label="瀹屽ソ" :value="1"></el-option>
- <el-option label="缁翠慨" :value="0"></el-option>
- </el-select> -->
- <el-input
- v-model="form.maintenanceResult"
- placeholder="璇疯緭鍏ヤ繚鍏荤粨鏋�"
- type="text" />
- </el-form-item>
- </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import dayjs from "dayjs";
-import useUserStore from "@/store/modules/user";
-
-defineOptions({
- name: "淇濆吇琛ㄥ崟",
-});
-
-const userStore = useUserStore();
-const { form, resetForm } = useFormData({
- maintenanceActuallyName: undefined, // 瀹為檯淇濆吇浜�
- maintenanceActuallyTime: undefined, // 瀹為檯淇濆吇鏃ユ湡
- maintenanceResult: undefined, // 淇濆吇缁撴灉
- status: 0, // 淇濆吇鐘舵��
-});
-
-const setForm = (data) => {
- form.maintenanceActuallyName =
- data.maintenanceActuallyName ?? userStore.nickName;
- form.maintenanceActuallyTime =
- dayjs(data.maintenanceActuallyTime).format("YYYY-MM-DD HH:mm:ss") ??
- dayjs().format("YYYY-MM-DD HH:mm:ss");
- form.maintenanceResult = data.maintenanceResult;
-};
-
-const getForm = () => {
- return form;
-};
-
-defineExpose({
- getForm,
- setForm,
- resetForm,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue b/src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue
new file mode 100644
index 0000000..c660840
--- /dev/null
+++ b/src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue
@@ -0,0 +1,123 @@
+<template>
+ <FormDialog
+ v-model="visible"
+ :title="'璁惧淇濆吇'"
+ width="500px"
+ @confirm="sendForm"
+ @cancel="handleCancel"
+ @close="handleClose"
+ >
+ <el-form :model="form" label-width="100px">
+ <el-form-item label="瀹為檯淇濆吇浜�">
+ <el-input
+ v-model="form.maintenanceActuallyName"
+ placeholder="璇疯緭鍏ュ疄闄呬繚鍏讳汉"
+ ></el-input>
+ </el-form-item>
+ <el-form-item label="瀹為檯淇濆吇鏃ユ湡">
+ <el-date-picker
+ v-model="form.maintenanceActuallyTime"
+ placeholder="璇烽�夋嫨瀹為檯淇濆吇鏃ユ湡"
+ format="YYYY-MM-DD HH:mm:ss"
+ value-format="YYYY-MM-DD HH:mm:ss"
+ type="datetime"
+ clearable
+ style="width: 100%"
+ />
+ </el-form-item>
+ <el-form-item label="淇濆吇鐘舵��">
+ <el-select v-model="form.status">
+ <el-option label="寰呬繚鍏�" :value="0"></el-option>
+ <el-option label="瀹岀粨" :value="1"></el-option>
+ <el-option label="澶辫触" :value="2"></el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item label="淇濆吇缁撴灉">
+ <el-input
+ v-model="form.maintenanceResult"
+ placeholder="璇疯緭鍏ヤ繚鍏荤粨鏋�"
+ type="text" />
+ </el-form-item>
+ </el-form>
+ </FormDialog>
+</template>
+
+<script setup>
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import { addMaintenance } from "@/api/equipmentManagement/upkeep";
+import useFormData from "@/hooks/useFormData";
+import dayjs from "dayjs";
+import useUserStore from "@/store/modules/user";
+import { ElMessage } from "element-plus";
+
+defineOptions({
+ name: "淇濆吇妯℃�佹",
+});
+
+const emits = defineEmits(["ok"]);
+
+// 淇濆瓨璁″垝淇濆吇璁板綍鐨刬d
+const planId = ref();
+const visible = ref(false);
+const loading = ref(false);
+const userStore = useUserStore();
+
+const { form, resetForm } = useFormData({
+ maintenanceActuallyName: undefined, // 瀹為檯淇濆吇浜�
+ maintenanceActuallyTime: undefined, // 瀹為檯淇濆吇鏃ユ湡
+ maintenanceResult: undefined, // 淇濆吇缁撴灉
+ status: 0, // 淇濆吇鐘舵��
+});
+
+const setForm = (data) => {
+ form.maintenanceActuallyName =
+ data.maintenanceActuallyName ?? userStore.nickName;
+ form.maintenanceActuallyTime =
+ data.maintenanceActuallyTime
+ ? dayjs(data.maintenanceActuallyTime).format("YYYY-MM-DD HH:mm:ss")
+ : dayjs().format("YYYY-MM-DD HH:mm:ss");
+ form.maintenanceResult = data.maintenanceResult;
+ form.status = 1; // 榛樿鐘舵�佷负瀹岀粨
+};
+
+/**
+ * @desc 淇濆瓨淇濆吇
+ */
+const sendForm = async () => {
+ loading.value = true;
+ try {
+ const { code } = await addMaintenance({ id: planId.value, ...form });
+ if (code == 200) {
+ ElMessage.success("淇濆吇鎴愬姛");
+ emits("ok");
+ resetForm();
+ visible.value = false;
+ }
+ } finally {
+ loading.value = false;
+ }
+};
+
+const handleCancel = () => {
+ resetForm();
+ visible.value = false;
+};
+
+const handleClose = () => {
+ resetForm();
+ visible.value = false;
+};
+
+const open = async (id, row) => {
+ planId.value = id; // 淇濆瓨璁″垝淇濆吇璁板綍鐨刬d
+ visible.value = true;
+ await nextTick();
+ setForm(row);
+};
+
+defineExpose({
+ open,
+});
+</script>
+
+<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Form/PlanForm.vue b/src/views/equipmentManagement/upkeep/Form/PlanForm.vue
deleted file mode 100644
index 2822e2c..0000000
--- a/src/views/equipmentManagement/upkeep/Form/PlanForm.vue
+++ /dev/null
@@ -1,137 +0,0 @@
-<template>
- <el-form :model="form" label-width="100px">
- <el-form-item label="璁惧鍚嶇О">
- <el-select
- v-model="form.deviceLedgerId"
- @change="setDeviceModel"
- placeholder="璇烽�夋嫨璁惧"
- filterable
- default-first-option
- :reserve-keyword="false"
- >
- <el-option
- v-for="(item, index) in deviceOptions"
- :key="index"
- :label="item.deviceName"
- :value="item.id"
- ></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="瑙勬牸鍨嬪彿">
- <el-input
- v-model="form.deviceModel"
- placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
- disabled
- />
- </el-form-item>
- <el-form-item label="褰曞叆浜�">
- <el-select
- v-model="form.createUser"
- placeholder="璇烽�夋嫨"
- filterable
- default-first-option
- :reserve-keyword="false"
- clearable
- >
- <el-option
- v-for="item in userList"
- :key="item.userId"
- :label="item.nickName"
- :value="item.userId"
- />
- </el-select>
- </el-form-item>
- <el-form-item v-if="id" label="淇濅慨鐘舵��">
- <el-select v-model="form.status">
- <el-option label="寰呬繚淇�" :value="0"></el-option>
- <el-option label="瀹岀粨" :value="1"></el-option>
- <el-option label="澶辫触" :value="2"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="璁″垝淇濆吇鏃ユ湡">
- <el-date-picker
- style="width: 100%"
- v-model="form.maintenancePlanTime"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD HH:mm:ss"
- type="date"
- placeholder="璇烽�夋嫨璁″垝淇濆吇鏃ユ湡鏃ユ湡"
- clearable
- />
- </el-form-item>
- </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
-import { onMounted } from "vue";
-import dayjs from "dayjs";
-import { userListNoPage } from "@/api/system/user.js";
-
-defineOptions({
- name: "璁″垝琛ㄥ崟",
-});
-
-const deviceOptions = ref([]);
-const loadDeviceName = async () => {
- const { data } = await getDeviceLedger();
- deviceOptions.value = data;
-};
-
-const { id } = defineProps(['id']);
-
-const { form, resetForm } = useFormData({
- deviceLedgerId: undefined, // 璁惧Id
- deviceName: undefined, // 璁惧鍚嶇О
- deviceModel: undefined, // 瑙勬牸鍨嬪彿
- maintenancePlanTime: undefined, // 璁″垝淇濆吇鏃ユ湡
- createUser: undefined, // 褰曞叆浜�
- status: 0, //淇濅慨鐘舵��
-});
-
-const setDeviceModel = (id) => {
- const option = deviceOptions.value.find((item) => item.id === id);
- form.deviceModel = option.deviceModel;
-};
-
-const getForm = () => {
- return form;
-};
-
-/**
- * @desc 璁剧疆琛ㄥ崟鍐呭
- * @param data 璁惧淇℃伅
- */
-const setForm = (data) => {
- form.deviceLedgerId = data.deviceLedgerId;
- form.deviceName = data.deviceName;
- form.deviceModel = data.deviceModel;
- form.createUser = Number(data.createUser);
- form.status = data.status;
- form.maintenancePlanTime = dayjs(data.maintenancePlanTime).format(
- "YYYY-MM-DD HH:mm:ss"
- );
-};
-
-// 鐢ㄦ埛鍒楄〃
-const userList = ref([]);
-
-const loadForm = () => {};
-
-onMounted(() => {
- loadDeviceName();
- userListNoPage().then((res) => {
- userList.value = res.data;
- });
-});
-
-defineExpose({
- loadForm,
- resetForm,
- getForm,
- setForm,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Form/PlanModal.vue b/src/views/equipmentManagement/upkeep/Form/PlanModal.vue
new file mode 100644
index 0000000..19095b9
--- /dev/null
+++ b/src/views/equipmentManagement/upkeep/Form/PlanModal.vue
@@ -0,0 +1,188 @@
+<template>
+ <FormDialog
+ v-model="visible"
+ :title="id ? '缂栬緫璁惧淇濆吇璁″垝' : '鏂板璁惧淇濆吇璁″垝'"
+ width="500px"
+ @confirm="sendForm"
+ @cancel="handleCancel"
+ @close="handleClose"
+ >
+ <el-form :model="form" label-width="100px">
+ <el-form-item label="璁惧鍚嶇О">
+ <el-select
+ v-model="form.deviceLedgerId"
+ @change="setDeviceModel"
+ placeholder="璇烽�夋嫨璁惧"
+ filterable
+ default-first-option
+ :reserve-keyword="false"
+ >
+ <el-option
+ v-for="(item, index) in deviceOptions"
+ :key="index"
+ :label="item.deviceName"
+ :value="item.id"
+ ></el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item label="瑙勬牸鍨嬪彿">
+ <el-input
+ v-model="form.deviceModel"
+ placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
+ disabled
+ />
+ </el-form-item>
+ <el-form-item label="褰曞叆浜�">
+ <el-select
+ v-model="form.createUser"
+ placeholder="璇烽�夋嫨"
+ filterable
+ default-first-option
+ :reserve-keyword="false"
+ clearable
+ >
+ <el-option
+ v-for="item in userList"
+ :key="item.userId"
+ :label="item.nickName"
+ :value="item.userId"
+ />
+ </el-select>
+ </el-form-item>
+ <el-form-item v-if="id" label="淇濅慨鐘舵��">
+ <el-select v-model="form.status">
+ <el-option label="寰呬繚淇�" :value="0"></el-option>
+ <el-option label="瀹岀粨" :value="1"></el-option>
+ <el-option label="澶辫触" :value="2"></el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item label="璁″垝淇濆吇鏃ユ湡">
+ <el-date-picker
+ style="width: 100%"
+ v-model="form.maintenancePlanTime"
+ format="YYYY-MM-DD"
+ value-format="YYYY-MM-DD HH:mm:ss"
+ type="date"
+ placeholder="璇烽�夋嫨璁″垝淇濆吇鏃ユ湡鏃ユ湡"
+ clearable
+ />
+ </el-form-item>
+ </el-form>
+ </FormDialog>
+</template>
+
+<script setup>
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import {
+ addUpkeep,
+ editUpkeep,
+ getUpkeepById,
+} from "@/api/equipmentManagement/upkeep";
+import { ElMessage } from "element-plus";
+import useFormData from "@/hooks/useFormData";
+import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
+import { onMounted } from "vue";
+import dayjs from "dayjs";
+import { userListNoPage } from "@/api/system/user.js";
+
+defineOptions({
+ name: "璁惧淇濆吇鏂板璁″垝",
+});
+
+const emits = defineEmits(["ok"]);
+
+const id = ref();
+const visible = ref(false);
+const loading = ref(false);
+
+const deviceOptions = ref([]);
+const loadDeviceName = async () => {
+ const { data } = await getDeviceLedger();
+ deviceOptions.value = data;
+};
+
+const { form, resetForm } = useFormData({
+ deviceLedgerId: undefined, // 璁惧Id
+ deviceName: undefined, // 璁惧鍚嶇О
+ deviceModel: undefined, // 瑙勬牸鍨嬪彿
+ maintenancePlanTime: undefined, // 璁″垝淇濆吇鏃ユ湡
+ createUser: undefined, // 褰曞叆浜�
+ status: 0, //淇濅慨鐘舵��
+});
+
+const setDeviceModel = (deviceId) => {
+ const option = deviceOptions.value.find((item) => item.id === deviceId);
+ form.deviceModel = option.deviceModel;
+};
+
+/**
+ * @desc 璁剧疆琛ㄥ崟鍐呭
+ * @param data 璁惧淇℃伅
+ */
+const setForm = (data) => {
+ form.deviceLedgerId = data.deviceLedgerId;
+ form.deviceName = data.deviceName;
+ form.deviceModel = data.deviceModel;
+ form.createUser = Number(data.createUser);
+ form.status = data.status;
+ form.maintenancePlanTime = dayjs(data.maintenancePlanTime).format(
+ "YYYY-MM-DD HH:mm:ss"
+ );
+};
+
+// 鐢ㄦ埛鍒楄〃
+const userList = ref([]);
+
+onMounted(() => {
+ loadDeviceName();
+ userListNoPage().then((res) => {
+ userList.value = res.data;
+ });
+});
+
+const openEdit = async (editId) => {
+ const { data } = await getUpkeepById(editId);
+ id.value = editId;
+ visible.value = true;
+ await nextTick();
+ setForm(data);
+};
+
+const sendForm = async () => {
+ loading.value = true;
+ try {
+ const { code } = id.value
+ ? await editUpkeep({ id: unref(id), ...form })
+ : await addUpkeep(form);
+ if (code == 200) {
+ ElMessage.success(`${id.value ? "缂栬緫" : "鏂板"}璁″垝鎴愬姛`);
+ visible.value = false;
+ emits("ok");
+ }
+ } finally {
+ loading.value = false;
+ }
+};
+
+const handleCancel = () => {
+ resetForm();
+ visible.value = false;
+};
+
+const handleClose = () => {
+ resetForm();
+ visible.value = false;
+};
+
+const openModal = () => {
+ id.value = undefined;
+ visible.value = true;
+};
+
+defineExpose({
+ openModal,
+ openEdit,
+});
+</script>
+
+<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Form/formDia.vue b/src/views/equipmentManagement/upkeep/Form/formDia.vue
new file mode 100644
index 0000000..66bf067
--- /dev/null
+++ b/src/views/equipmentManagement/upkeep/Form/formDia.vue
@@ -0,0 +1,304 @@
+<template>
+ <FormDialog
+ v-model="dialogVisitable"
+ :title="operationType === 'add' ? '鏂板淇濆吇浠诲姟' : '缂栬緫淇濆吇浠诲姟'"
+ width="800px"
+ :operation-type="operationType"
+ @confirm="submitForm"
+ @cancel="cancel"
+ @close="cancel"
+ >
+ <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
+ <el-row>
+ <el-col :span="12">
+ <el-form-item label="璁惧鍚嶇О" prop="taskId">
+ <el-select v-model="form.taskId" @change="setDeviceModel" filterable>
+ <el-option
+ v-for="(item, index) in deviceOptions"
+ :key="index"
+ :label="item.deviceName"
+ :value="item.id"
+ ></el-option>
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="瑙勬牸鍨嬪彿">
+ <el-input
+ v-model="form.deviceModel"
+ placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
+ disabled
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row>
+ <el-col :span="12">
+ <el-form-item label="褰曞叆浜�" prop="inspector">
+ <el-select
+ v-model="form.inspector"
+ filterable
+ default-first-option
+ :reserve-keyword="false"
+ placeholder="璇烽�夋嫨"
+ clearable
+ >
+ <el-option
+ v-for="item in userList"
+ :label="item.nickName"
+ :value="item.userId"
+ :key="item.userId"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鐧昏鏃堕棿" prop="registrationDate">
+ <el-date-picker
+ v-model="form.registrationDate"
+ type="date"
+ placeholder="閫夋嫨鐧昏鏃ユ湡"
+ format="YYYY-MM-DD"
+ value-format="YYYY-MM-DD"
+ style="width: 100%"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row>
+ <el-col :span="12">
+ <el-form-item label="浠诲姟棰戠巼" prop="frequencyType">
+ <el-select v-model="form.frequencyType" placeholder="璇烽�夋嫨" clearable>
+ <el-option label="姣忔棩" value="DAILY"/>
+ <el-option label="姣忓懆" value="WEEKLY"/>
+ <el-option label="姣忔湀" value="MONTHLY"/>
+ <el-option label="瀛e害" value="QUARTERLY"/>
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12" v-if="form.frequencyType === 'DAILY' && form.frequencyType">
+ <el-form-item label="鏃ユ湡" prop="frequencyDetail">
+ <el-time-picker v-model="form.frequencyDetail" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
+ value-format="HH:mm" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12" v-if="form.frequencyType === 'WEEKLY' && form.frequencyType">
+ <el-form-item label="鏃ユ湡" prop="frequencyDetail">
+ <el-select v-model="form.week" placeholder="璇烽�夋嫨" clearable style="width: 50%">
+ <el-option label="鍛ㄤ竴" value="MON"/>
+ <el-option label="鍛ㄤ簩" value="TUE"/>
+ <el-option label="鍛ㄤ笁" value="WED"/>
+ <el-option label="鍛ㄥ洓" value="THU"/>
+ <el-option label="鍛ㄤ簲" value="FRI"/>
+ <el-option label="鍛ㄥ叚" value="SAT"/>
+ <el-option label="鍛ㄦ棩" value="SUN"/>
+ </el-select>
+ <el-time-picker v-model="form.time" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
+ value-format="HH:mm" style="width: 50%"/>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12" v-if="form.frequencyType === 'MONTHLY' && form.frequencyType">
+ <el-form-item label="鏃ユ湡" prop="frequencyDetail">
+ <el-date-picker
+ v-model="form.frequencyDetail"
+ type="datetime"
+ clearable
+ placeholder="閫夋嫨寮�濮嬫棩鏈�"
+ format="DD,HH:mm"
+ value-format="DD,HH:mm"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12" v-if="form.frequencyType === 'QUARTERLY' && form.frequencyType">
+ <el-form-item label="鏃ユ湡" prop="frequencyDetail">
+ <el-date-picker
+ v-model="form.frequencyDetail"
+ type="datetime"
+ clearable
+ placeholder="閫夋嫨寮�濮嬫棩鏈�"
+ format="MM,DD,HH:mm"
+ value-format="MM,DD,HH:mm"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row>
+ <el-col :span="12">
+ <el-form-item label="澶囨敞" prop="remarks">
+ <el-input v-model="form.remarks" placeholder="璇疯緭鍏ュ娉�" type="textarea" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ </FormDialog>
+</template>
+
+<script setup>
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import { reactive, ref, getCurrentInstance, toRefs } from "vue";
+import {userListNoPageByTenantId} from "@/api/system/user.js";
+import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
+import { deviceMaintenanceTaskAdd, deviceMaintenanceTaskEdit } from "@/api/equipmentManagement/upkeep";
+import { getCurrentDate } from "@/utils/index.js";
+import useUserStore from "@/store/modules/user.js";
+
+const { proxy } = getCurrentInstance()
+const emit = defineEmits()
+const dialogVisitable = ref(false);
+const operationType = ref('add');
+const deviceOptions = ref([]);
+const userStore = useUserStore();
+const data = reactive({
+ form: {
+ taskId: undefined,
+ taskName: undefined,
+ // 褰曞叆浜猴細鍗曢�変竴涓敤鎴� id
+ inspector: undefined,
+ remarks: '',
+ frequencyType: '',
+ frequencyDetail: '',
+ week: '',
+ time: '',
+ deviceModel: undefined, // 瑙勬牸鍨嬪彿
+ registrationDate: ''
+ },
+ rules: {
+ taskId: [{ required: true, message: "璇烽�夋嫨璁惧", trigger: "change" },],
+ inspector: [{ required: true, message: "璇烽�夋嫨褰曞叆浜�", trigger: "blur" },],
+ registrationDate: [{ required: true, message: "璇烽�夋嫨鐧昏鏃堕棿", trigger: "change" }]
+ }
+})
+const { form, rules } = toRefs(data)
+const userList = ref([])
+
+const loadDeviceName = async () => {
+ const { data } = await getDeviceLedger();
+ deviceOptions.value = data;
+};
+
+// 閫夋嫨璁惧鏃讹紝鍥炲~璁惧鍚嶇О(taskName)鍜岃鏍煎瀷鍙�(deviceModel)
+const setDeviceModel = (id) => {
+ const option = deviceOptions.value.find((item) => item.id === id);
+ if (option) {
+ form.value.taskId = option.id;
+ form.value.taskName = option.deviceName;
+ form.value.deviceModel = option.deviceModel;
+ }
+}
+
+// 鎵撳紑寮规
+const openDialog = async (type, row) => {
+ dialogVisitable.value = true
+ operationType.value = type
+
+ // 閲嶇疆琛ㄥ崟
+ resetForm();
+
+ // 鍔犺浇鐢ㄦ埛鍒楄〃
+ userListNoPageByTenantId().then((res) => {
+ userList.value = res.data;
+ });
+
+ // 鍔犺浇璁惧鍒楄〃
+ await loadDeviceName();
+
+ if (type === 'edit' && row) {
+ form.value = { ...row }
+ // 缂栬緫鏃剁敤鎺ュ彛杩斿洖鐨� registrantId 鍥炴樉褰曞叆浜�
+ if (row.registrantId) {
+ form.value.inspector = row.registrantId
+ }
+
+ // 濡傛灉鏈夎澶嘔D锛岃嚜鍔ㄨ缃澶囦俊鎭�
+ if (form.value.taskId) {
+ setDeviceModel(form.value.taskId);
+ }
+ } else if (type === 'add') {
+ // 鏂板鏃惰缃櫥璁版棩鏈熶负褰撳ぉ
+ form.value.registrationDate = getCurrentDate();
+ // 鏂板鏃惰缃綍鍏ヤ汉涓哄綋鍓嶇櫥褰曡处鎴�
+ form.value.inspector = userStore.id;
+ }
+}
+
+// 鍏抽棴瀵硅瘽妗�
+const cancel = () => {
+ resetForm()
+ dialogVisitable.value = false
+ emit('closeDia')
+}
+
+// 閲嶇疆琛ㄥ崟鍑芥暟
+const resetForm = () => {
+ if (proxy.$refs.formRef) {
+ proxy.$refs.formRef.resetFields()
+ }
+ // 閲嶇疆琛ㄥ崟鏁版嵁纭繚璁惧淇℃伅姝g‘閲嶇疆
+ form.value = {
+ taskId: undefined,
+ taskName: undefined,
+ inspector: undefined,
+ inspector: undefined,
+ remarks: '',
+ frequencyType: '',
+ frequencyDetail: '',
+ week: '',
+ time: '',
+ deviceModel: undefined,
+ registrationDate: ''
+ }
+}
+
+// 鎻愪氦琛ㄥ崟
+const submitForm = () => {
+ proxy.$refs["formRef"].validate(async valid => {
+ if (valid) {
+ try {
+ const payload = { ...form.value }
+ // 涓嶅啀鍚戝悗绔紶淇濆吇浜哄瓧娈碉紝浠呬娇鐢ㄦ帴鍙h姹傜殑 registrant / registrantId
+ // 鏍规嵁閫夋嫨鐨�"褰曞叆浜�"璁剧疆 registrant / registrantId
+ if (payload.inspector) {
+ const selectedUser = userList.value.find(
+ (u) => String(u.userId) === String(payload.inspector)
+ )
+ if (selectedUser) {
+ payload.registrantId = selectedUser.userId
+ payload.registrant = selectedUser.nickName
+ }
+ }
+ delete payload.inspector
+ delete payload.inspectorIds
+
+ if (payload.frequencyType === 'WEEKLY') {
+ let frequencyDetail = ''
+ frequencyDetail = payload.week + ',' + payload.time
+ payload.frequencyDetail = frequencyDetail
+ }
+
+ // 褰曞叆鏃ユ湡锛氱洿鎺ヤ娇鐢ㄨ〃鍗曢噷鐨� registrationDate 瀛楁
+ // 涓�浜涢粯璁ょ姸鎬佸瓧娈�
+ if (payload.status === undefined || payload.status === null || payload.status === '') {
+ payload.status = '0' // 榛樿鐘舵�侊紝鍙寜瀹為檯鏋氫妇璋冩暣
+ }
+ payload.active = true
+ payload.deleted = 0
+
+ if (operationType.value === 'edit') {
+ await deviceMaintenanceTaskEdit(payload)
+ } else {
+ await deviceMaintenanceTaskAdd(payload)
+ }
+ cancel()
+ proxy.$modal.msgSuccess('鎻愪氦鎴愬姛')
+ } catch (error) {
+ proxy.$modal.msgError('鎻愪氦澶辫触锛岃閲嶈瘯')
+ }
+ }
+ })
+}
+defineExpose({ openDialog })
+</script>
+
+<style scoped>
+
+</style>
diff --git a/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue b/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue
deleted file mode 100644
index 0b44221..0000000
--- a/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue
+++ /dev/null
@@ -1,60 +0,0 @@
-<template>
- <el-dialog v-model="visible" :title="modalOptions.title" direction="ltr" draggable>
- <MaintenanceForm ref="maintenanceFormRef" />
- <template #footer>
- <el-button type="primary" @click="sendForm" :loading="loading">
- {{ modalOptions.confirmText }}
- </el-button>
- <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
- </template>
- </el-dialog>
-</template>
-
-<script setup>
-import MaintenanceForm from "../Form/MaintenanceForm.vue";
-import { useModal } from "@/hooks/useModal";
-import { addMaintenance } from "@/api/equipmentManagement/upkeep";
-
-defineOptions({
- name: "淇濆吇妯℃�佹",
-});
-
-const maintenanceFormRef = ref();
-const emits = defineEmits(["ok"]);
-
-const {
- id,
- visible,
- loading,
- openModal,
- modalOptions,
- handleConfirm,
- closeModal,
-} = useModal({ title: "璁惧淇濆吇" });
-
-/**
- * @desc 淇濆瓨淇濆吇
- */
-const sendForm = async () => {
- loading.value = true;
- const form = await maintenanceFormRef.value.getForm();
- const { code } = await addMaintenance({ id: id.value, ...form });
- if (code == 200) {
- emits("ok");
- maintenanceFormRef.value.resetForm();
- closeModal();
- }
- loading.value = false;
-};
-
-const open = async (id, row) => {
- openModal(id);
- await nextTick();
- maintenanceFormRef.value.setForm(row);
-};
-defineExpose({
- open,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Modal/PlanModal.vue b/src/views/equipmentManagement/upkeep/Modal/PlanModal.vue
deleted file mode 100644
index 249c9c3..0000000
--- a/src/views/equipmentManagement/upkeep/Modal/PlanModal.vue
+++ /dev/null
@@ -1,77 +0,0 @@
-<template>
- <el-dialog
- v-model="visible"
- :title="modalOptions.title"
- width="30%"
- draggable
- @close="close"
- >
- <PlanForm ref="planFormRef" :id="id"></PlanForm>
- <template #footer>
- <el-button type="primary" @click="sendForm" :loading="loading">
- {{ modalOptions.confirmText }}
- </el-button>
- <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
- </template>
- </el-dialog>
-</template>
-
-<script setup>
-import { useModal } from "@/hooks/useModal";
-import PlanForm from "../Form/PlanForm";
-import {
- addUpkeep,
- editUpkeep,
- getUpkeepById,
-} from "@/api/equipmentManagement/upkeep";
-import { ElMessage } from "element-plus";
-
-defineOptions({
- name: "璁惧淇濆吇鏂板璁″垝",
-});
-
-const emits = defineEmits(["ok"]);
-const planFormRef = ref();
-const {
- id,
- visible,
- loading,
- openModal,
- modalOptions,
- handleConfirm,
- closeModal,
-} = useModal({ title: "璁惧淇濆吇璁″垝" });
-
-const openEdit = async (id) => {
- const { data } = await getUpkeepById(id);
- openModal(id);
- await nextTick();
- await planFormRef.value.setForm(data);
-};
-
-const sendForm = async () => {
- loading.value = true;
- const form = await planFormRef.value.getForm();
- const { code } = id.value
- ? await editUpkeep({ id: unref(id), ...form })
- : await addUpkeep(form);
- if (code == 200) {
- ElMessage.success(`${id ? "缂栬緫" : "鏂板"}璁″垝鎴愬姛`);
- closeModal();
- emits("ok");
- }
- loading.value = false;
-};
-
-const close = () => {
- planFormRef.value.resetForm();
- closeModal();
-};
-
-defineExpose({
- openModal,
- openEdit,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Modal/formDia.vue b/src/views/equipmentManagement/upkeep/Modal/formDia.vue
deleted file mode 100644
index a484d23..0000000
--- a/src/views/equipmentManagement/upkeep/Modal/formDia.vue
+++ /dev/null
@@ -1,304 +0,0 @@
-<template>
- <div>
- <el-dialog :title="operationType === 'add' ? '鏂板淇濆吇浠诲姟' : '缂栬緫淇濆吇浠诲姟'"
- v-model="dialogVisitable" width="800px" @close="cancel">
- <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
- <el-row>
- <el-col :span="12">
- <el-form-item label="璁惧鍚嶇О" prop="taskId">
- <el-select v-model="form.taskId" @change="setDeviceModel" filterable>
- <el-option
- v-for="(item, index) in deviceOptions"
- :key="index"
- :label="item.deviceName"
- :value="item.id"
- ></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="瑙勬牸鍨嬪彿">
- <el-input
- v-model="form.deviceModel"
- placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
- disabled
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-col :span="12">
- <el-form-item label="褰曞叆浜�" prop="inspector">
- <el-select
- v-model="form.inspector"
- filterable
- default-first-option
- :reserve-keyword="false"
- placeholder="璇烽�夋嫨"
- clearable
- >
- <el-option
- v-for="item in userList"
- :label="item.nickName"
- :value="item.userId"
- :key="item.userId"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鐧昏鏃堕棿" prop="registrationDate">
- <el-date-picker
- v-model="form.registrationDate"
- type="date"
- placeholder="閫夋嫨鐧昏鏃ユ湡"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-col :span="12">
- <el-form-item label="浠诲姟棰戠巼" prop="frequencyType">
- <el-select v-model="form.frequencyType" placeholder="璇烽�夋嫨" clearable>
- <el-option label="姣忔棩" value="DAILY"/>
- <el-option label="姣忓懆" value="WEEKLY"/>
- <el-option label="姣忔湀" value="MONTHLY"/>
- <el-option label="瀛e害" value="QUARTERLY"/>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12" v-if="form.frequencyType === 'DAILY' && form.frequencyType">
- <el-form-item label="鏃ユ湡" prop="frequencyDetail">
- <el-time-picker v-model="form.frequencyDetail" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
- value-format="HH:mm" />
- </el-form-item>
- </el-col>
- <el-col :span="12" v-if="form.frequencyType === 'WEEKLY' && form.frequencyType">
- <el-form-item label="鏃ユ湡" prop="frequencyDetail">
- <el-select v-model="form.week" placeholder="璇烽�夋嫨" clearable style="width: 50%">
- <el-option label="鍛ㄤ竴" value="MON"/>
- <el-option label="鍛ㄤ簩" value="TUE"/>
- <el-option label="鍛ㄤ笁" value="WED"/>
- <el-option label="鍛ㄥ洓" value="THU"/>
- <el-option label="鍛ㄤ簲" value="FRI"/>
- <el-option label="鍛ㄥ叚" value="SAT"/>
- <el-option label="鍛ㄦ棩" value="SUN"/>
- </el-select>
- <el-time-picker v-model="form.time" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
- value-format="HH:mm" style="width: 50%"/>
- </el-form-item>
- </el-col>
- <el-col :span="12" v-if="form.frequencyType === 'MONTHLY' && form.frequencyType">
- <el-form-item label="鏃ユ湡" prop="frequencyDetail">
- <el-date-picker
- v-model="form.frequencyDetail"
- type="datetime"
- clearable
- placeholder="閫夋嫨寮�濮嬫棩鏈�"
- format="DD,HH:mm"
- value-format="DD,HH:mm"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12" v-if="form.frequencyType === 'QUARTERLY' && form.frequencyType">
- <el-form-item label="鏃ユ湡" prop="frequencyDetail">
- <el-date-picker
- v-model="form.frequencyDetail"
- type="datetime"
- clearable
- placeholder="閫夋嫨寮�濮嬫棩鏈�"
- format="MM,DD,HH:mm"
- value-format="MM,DD,HH:mm"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-col :span="12">
- <el-form-item label="澶囨敞" prop="remarks">
- <el-input v-model="form.remarks" placeholder="璇疯緭鍏ュ娉�" type="textarea" />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitForm">淇濆瓨</el-button>
- <el-button @click="cancel">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { reactive, ref, getCurrentInstance, toRefs } from "vue";
-import {userListNoPageByTenantId} from "@/api/system/user.js";
-import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
-import { deviceMaintenanceTaskAdd, deviceMaintenanceTaskEdit } from "@/api/equipmentManagement/upkeep";
-import { getCurrentDate } from "@/utils/index.js";
-import useUserStore from "@/store/modules/user.js";
-
-const { proxy } = getCurrentInstance()
-const emit = defineEmits()
-const dialogVisitable = ref(false);
-const operationType = ref('add');
-const deviceOptions = ref([]);
-const userStore = useUserStore();
-const data = reactive({
- form: {
- taskId: undefined,
- taskName: undefined,
- // 褰曞叆浜猴細鍗曢�変竴涓敤鎴� id
- inspector: undefined,
- remarks: '',
- frequencyType: '',
- frequencyDetail: '',
- week: '',
- time: '',
- deviceModel: undefined, // 瑙勬牸鍨嬪彿
- registrationDate: ''
- },
- rules: {
- taskId: [{ required: true, message: "璇烽�夋嫨璁惧", trigger: "change" },],
- inspector: [{ required: true, message: "璇烽�夋嫨褰曞叆浜�", trigger: "blur" },],
- registrationDate: [{ required: true, message: "璇烽�夋嫨鐧昏鏃堕棿", trigger: "change" }]
- }
-})
-const { form, rules } = toRefs(data)
-const userList = ref([])
-
-const loadDeviceName = async () => {
- const { data } = await getDeviceLedger();
- deviceOptions.value = data;
-};
-
-// 閫夋嫨璁惧鏃讹紝鍥炲~璁惧鍚嶇О(taskName)鍜岃鏍煎瀷鍙�(deviceModel)
-const setDeviceModel = (id) => {
- const option = deviceOptions.value.find((item) => item.id === id);
- if (option) {
- form.value.taskId = option.id;
- form.value.taskName = option.deviceName;
- form.value.deviceModel = option.deviceModel;
- }
-}
-
-// 鎵撳紑寮规
-const openDialog = async (type, row) => {
- dialogVisitable.value = true
- operationType.value = type
-
- // 閲嶇疆琛ㄥ崟
- resetForm();
-
- // 鍔犺浇鐢ㄦ埛鍒楄〃
- userListNoPageByTenantId().then((res) => {
- userList.value = res.data;
- });
-
- // 鍔犺浇璁惧鍒楄〃
- await loadDeviceName();
-
- if (type === 'edit' && row) {
- form.value = { ...row }
- // 缂栬緫鏃剁敤鎺ュ彛杩斿洖鐨� registrantId 鍥炴樉褰曞叆浜�
- if (row.registrantId) {
- form.value.inspector = row.registrantId
- }
-
- // 濡傛灉鏈夎澶嘔D锛岃嚜鍔ㄨ缃澶囦俊鎭�
- if (form.value.taskId) {
- setDeviceModel(form.value.taskId);
- }
- } else if (type === 'add') {
- // 鏂板鏃惰缃櫥璁版棩鏈熶负褰撳ぉ
- form.value.registrationDate = getCurrentDate();
- // 鏂板鏃惰缃綍鍏ヤ汉涓哄綋鍓嶇櫥褰曡处鎴�
- form.value.inspector = userStore.id;
- }
-}
-
-// 鍏抽棴瀵硅瘽妗�
-const cancel = () => {
- resetForm()
- dialogVisitable.value = false
- emit('closeDia')
-}
-
-// 閲嶇疆琛ㄥ崟鍑芥暟
-const resetForm = () => {
- if (proxy.$refs.formRef) {
- proxy.$refs.formRef.resetFields()
- }
- // 閲嶇疆琛ㄥ崟鏁版嵁纭繚璁惧淇℃伅姝g‘閲嶇疆
- form.value = {
- taskId: undefined,
- taskName: undefined,
- inspector: undefined,
- inspector: undefined,
- remarks: '',
- frequencyType: '',
- frequencyDetail: '',
- week: '',
- time: '',
- deviceModel: undefined,
- registrationDate: ''
- }
-}
-
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
- proxy.$refs["formRef"].validate(async valid => {
- if (valid) {
- try {
- const payload = { ...form.value }
- // 涓嶅啀鍚戝悗绔紶淇濆吇浜哄瓧娈碉紝浠呬娇鐢ㄦ帴鍙h姹傜殑 registrant / registrantId
- // 鏍规嵁閫夋嫨鐨勨�滃綍鍏ヤ汉鈥濊缃� registrant / registrantId
- if (payload.inspector) {
- const selectedUser = userList.value.find(
- (u) => String(u.userId) === String(payload.inspector)
- )
- if (selectedUser) {
- payload.registrantId = selectedUser.userId
- payload.registrant = selectedUser.nickName
- }
- }
- delete payload.inspector
- delete payload.inspectorIds
-
- if (payload.frequencyType === 'WEEKLY') {
- let frequencyDetail = ''
- frequencyDetail = payload.week + ',' + payload.time
- payload.frequencyDetail = frequencyDetail
- }
-
- // 褰曞叆鏃ユ湡锛氱洿鎺ヤ娇鐢ㄨ〃鍗曢噷鐨� registrationDate 瀛楁
- // 涓�浜涢粯璁ょ姸鎬佸瓧娈�
- if (payload.status === undefined || payload.status === null || payload.status === '') {
- payload.status = '0' // 榛樿鐘舵�侊紝鍙寜瀹為檯鏋氫妇璋冩暣
- }
- payload.active = true
- payload.deleted = 0
-
- if (operationType.value === 'edit') {
- await deviceMaintenanceTaskEdit(payload)
- } else {
- await deviceMaintenanceTaskAdd(payload)
- }
- cancel()
- proxy.$modal.msgSuccess('鎻愪氦鎴愬姛')
- } catch (error) {
- proxy.$modal.msgError('鎻愪氦澶辫触锛岃閲嶈瘯')
- }
- }
- })
-}
-defineExpose({ openDialog })
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/upkeep/index.vue b/src/views/equipmentManagement/upkeep/index.vue
index 9b13b47..44f4af7 100644
--- a/src/views/equipmentManagement/upkeep/index.vue
+++ b/src/views/equipmentManagement/upkeep/index.vue
@@ -64,16 +64,14 @@
<template #operation="{ row }">
<el-button
type="primary"
- text
- icon="editPen"
+ link
@click="editScheduledTask(row)"
>
缂栬緫
</el-button>
<el-button
type="danger"
- text
- icon="delete"
+ link
@click="delScheduledTaskByIds(row.id)"
>
鍒犻櫎
@@ -135,14 +133,6 @@
<div class="actions">
<el-text class="mx-1" size="large">浠诲姟璁板綍</el-text>
<div>
- <el-button
- type="primary"
- icon="Plus"
- :disabled="multipleList.length !== 1"
- @click="addMaintain"
- >
- 鏂板淇濆吇
- </el-button>
<el-button type="success" icon="Van" @click="addPlan">
鏂板璁″垝
</el-button>
@@ -152,7 +142,7 @@
<el-button
type="danger"
icon="Delete"
- :disabled="multipleList.length <= 0"
+ :disabled="multipleList.length <= 0 || hasFinishedStatus"
@click="delRepairByIds(multipleList.map((item) => item.id))"
>
鎵归噺鍒犻櫎
@@ -183,16 +173,24 @@
<template #operation="{ row }">
<el-button
type="primary"
- text
- icon="editPen"
+ link
+ :disabled="row.status === 1"
@click="editPlan(row.id)"
>
缂栬緫
</el-button>
<el-button
+ type="success"
+ link
+ :disabled="row.status === 1"
+ @click="addMaintain(row)"
+ >
+ 淇濆吇
+ </el-button>
+ <el-button
type="danger"
- text
- icon="delete"
+ link
+ :disabled="row.status === 1"
@click="delRepairByIds(row.id)"
>
鍒犻櫎
@@ -209,12 +207,12 @@
</template>
<script setup>
-import { ref, onMounted, reactive, getCurrentInstance, nextTick } from 'vue'
+import { ref, onMounted, reactive, getCurrentInstance, nextTick, computed } from 'vue'
import { Search } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
-import PlanModal from './Modal/PlanModal.vue'
-import MaintenanceModal from './Modal/MaintenanceModal.vue'
-import FormDia from './Modal/formDia.vue'
+import PlanModal from './Form/PlanModal.vue'
+import MaintenanceModal from './Form/MaintenanceModal.vue'
+import FormDia from './Form/formDia.vue'
import {
getUpkeepPage,
delUpkeep,
@@ -494,14 +492,18 @@
multipleList.value = selection
}
+// 妫�鏌ラ�変腑鐨勮褰曚腑鏄惁鏈夊畬缁撶姸鎬佺殑
+const hasFinishedStatus = computed(() => {
+ return multipleList.value.some(item => item.status === 1)
+})
+
const changePage = (page) => {
pagination.value.currentPage = page.page
pagination.value.pageSize = page.limit
getTableData()
}
-const addMaintain = () => {
- const row = multipleList.value[0]
+const addMaintain = (row) => {
maintainModalRef.value.open(row.id, row)
}
@@ -514,6 +516,13 @@
}
const delRepairByIds = async (ids) => {
+ // 妫�鏌ユ槸鍚︽湁瀹岀粨鐘舵�佺殑璁板綍
+ const hasFinished = multipleList.value.some(item => item.status === 1)
+ if (hasFinished) {
+ ElMessage.warning('涓嶈兘鍒犻櫎鐘舵�佷负瀹岀粨鐨勮褰�')
+ return
+ }
+
try {
await ElMessageBox.confirm('纭鍒犻櫎淇濆吇鏁版嵁, 姝ゆ搷浣滀笉鍙��?', '璀﹀憡', {
confirmButtonText: '纭畾',
diff --git a/src/views/financialManagement/accounting/index.vue b/src/views/financialManagement/accounting/index.vue
index 91588fd..40bf1ae 100644
--- a/src/views/financialManagement/accounting/index.vue
+++ b/src/views/financialManagement/accounting/index.vue
@@ -2,14 +2,31 @@
<div style="padding: 20px;">
<!-- 椤甸潰鏍囬鍜岀瓫閫夋潯浠� -->
<div class="w-full md:w-auto flex items-center gap-3" style="margin-bottom: 20px;">
- <el-button
- type="primary"
- icon="Refresh"
- @click="resetFilters"
- size="default"
- >
- 鏌ヨ
- </el-button>
+ <el-form :inline="true">
+ <el-form-item label="骞翠唤">
+ <el-date-picker
+ v-model="selectedYear"
+ type="year"
+ placeholder="璇烽�夋嫨骞翠唤"
+ format="YYYY"
+ value-format="YYYY"
+ clearable
+ @change="fetchData()"
+ style="width: 200px"
+ :disabled-date="(date) => date.getFullYear() > new Date().getFullYear()"
+ />
+ </el-form-item>
+ <el-form-item>
+ <el-button
+ type="primary"
+ icon="Refresh"
+ @click="resetFilters"
+ size="default"
+ >
+ 閲嶇疆
+ </el-button>
+ </el-form-item>
+ </el-form>
</div>
<main class="container mx-auto px-4 pb-10">
@@ -27,7 +44,7 @@
<el-card class="bg3">
<p>璧勪骇鍘熷��</p>
<h3>
- 楼{{ assetInfo.totalOriginalValue }}
+ 楼{{ formatCurrency(assetInfo.totalOriginalValue) }}
</h3>
</el-card>
@@ -35,7 +52,7 @@
<el-card class="bg4">
<p>绱鎶樻棫</p>
<h3>
- 楼{{ assetInfo.totalDepreciation }}
+ 楼{{ formatCurrency(assetInfo.totalDepreciation) }}
</h3>
</el-card>
@@ -43,7 +60,21 @@
<el-card class="bg5">
<p>鍑�鍊�</p>
<h3>
- 楼{{ assetInfo.totalNetValue }}
+ 楼{{ formatCurrency(assetInfo.totalNetValue) }}
+ </h3>
+ </el-card>
+ <!-- 璐熷�� -->
+ <el-card class="bg2">
+ <p>璐熷��</p>
+ <h3>
+ 楼{{ formatCurrency(assetInfo.debt) }}
+ </h3>
+ </el-card>
+ <!-- 搴撳瓨璧勪骇 -->
+ <el-card class="bg3">
+ <p>搴撳瓨璧勪骇</p>
+ <h3>
+ 楼{{ formatCurrency(assetInfo.inventoryValue) }}
</h3>
</el-card>
</div>
@@ -62,7 +93,7 @@
style="height: 260px; width: 35%;">
<div class="chart-num">
<span style="font-size: 22px;">璁惧绫诲瀷</span>
- <span style="font-size: 36px; font-weight: 500; font-family: 'MyCustomFont', sans-serif;">{{ assetInfo.totalEquipment }}</span>
+ <span style="font-size: 36px; font-weight: 500; font-family: 'MyCustomFont', sans-serif;">{{ deviceTypeTotalCount }}</span>
</div>
</Echarts>
<Echarts
@@ -86,7 +117,6 @@
style="width: 100%"
:header-cell-style="{ background: '#f5f7fa', color: '#606266' }"
>
- <el-table-column prop="id" label="璧勪骇缂栧彿" width="120" />
<el-table-column prop="deviceName" label="璁惧鍚嶇О" width="250" />
<el-table-column prop="deviceModel" label="鍨嬪彿瑙勬牸" min-width="150" />
<el-table-column prop="supplierName" label="渚涘簲鍟�" min-width="120" />
@@ -94,27 +124,17 @@
<el-table-column prop="number" label="鏁伴噺" width="120" />
<el-table-column prop="originalValue" label="鍘熷��(鍏�)" width="120">
<template #default="{ row }">
- 楼{{ formatCurrency(row.taxIncludingPriceTotal) }}
+ {{ formatCurrency(row.taxIncludingPriceTotal) }}
</template>
</el-table-column>
<el-table-column prop="depreciation" label="绱鎶樻棫(鍏�)" width="140">
<template #default="{ row }">
- 楼{{ formatCurrency(row.taxIncludingPriceTotal-row.unTaxIncludingPriceTotal) }}
+ {{ formatCurrency(row.deprAmount) }}
</template>
</el-table-column>
<el-table-column prop="netValue" label="鍑�鍊�(鍏�)" width="120">
<template #default="{ row }">
- 楼{{ formatCurrency(row.unTaxIncludingPriceTotal) }}
- </template>
- </el-table-column>
- <el-table-column prop="status" label="鐘舵��" width="100">
- <template #default="{ row }">
- <el-tag
- :type="getStatusTagType(row.status)"
- size="small"
- >
- {{ row.status }}
- </el-tag>
+ {{ formatCurrency(row.netValue) }}
</template>
</el-table-column>
</el-table>
@@ -142,20 +162,27 @@
import 'element-plus/dist/index.css';
import Echarts from "@/components/Echarts/echarts.vue";
import { getLedgerPage } from "@/api/equipmentManagement/ledger";
+import { getAccountingTotal, getDeviceTypeDistribution, getCalculateDepreciation } from "@/api/financialManagement/accounting";
import dayjs from "dayjs";
// 绛涢�夋潯浠�
const dateRange = ref(null);
const equipmentType = ref('');
+const selectedYear = ref(dayjs().format('YYYY')); // 榛樿褰撳墠骞翠唤
// 鍥哄畾璧勪骇淇℃伅
const assetInfo = ref({
- totalEquipment: 0,
- totalOriginalValue: 0,
- totalDepreciation: 0,
- totalNetValue: 0
+ totalEquipment: 0, // deviceTotal
+ totalOriginalValue: 0, // deviceAmount
+ totalDepreciation: 0, // deprAmount
+ totalNetValue: 0, // netValue
+ debt: 0, // 璐熷��
+ inventoryValue: 0 // 搴撳瓨璧勪骇
});
+
+// 璁惧绫诲瀷鎬绘暟锛堢敤浜庡浘琛ㄦ樉绀猴級
+const deviceTypeTotalCount = ref(0);
// 璁惧鍒楄〃
const equipmentList = ref([]);
@@ -306,63 +333,96 @@
const fetchData = async () => {
try {
// 鑾峰彇鍥哄畾璧勪骇姹囨�讳俊鎭�
- const assetInfoRes = await getAssetInfo({
+ const assetInfoRes = await getAccountingTotal({
startDate: dateRange.value ? dateRange.value[0] : null,
endDate: dateRange.value ? dateRange.value[1] : null,
- equipmentType: equipmentType.value
+ equipmentType: equipmentType.value,
+ year: selectedYear.value
});
if (assetInfoRes.code === 200) {
- assetInfo.value = assetInfoRes.data;
+ // 鏄犲皠鍚庣瀛楁鍒板墠绔瓧娈�
+ const data = assetInfoRes.data;
+ assetInfo.value = {
+ totalEquipment: data.deviceTotal || 0, // 璁惧鎬绘暟
+ totalOriginalValue: data.deviceAmount || 0, // 璧勪骇鍘熷��
+ totalDepreciation: data.deprAmount || 0, // 绱鎶樻棫
+ totalNetValue: data.netValue || 0, // 鍑�鍊�
+ debt: data.debt || 0, // 璐熷��
+ inventoryValue: data.inventoryValue || 0 // 搴撳瓨璧勪骇
+ };
}
- // 鑾峰彇璁惧鍒楄〃
- const equipmentListRes = await getLedgerPage({
- current: pagination.value.currentPage,
- size: pagination.value.pageSize,
+ // 鑾峰彇璁惧绫诲瀷鍒嗗竷鏁版嵁锛堥ゼ鍥惧拰鎶樼嚎鍥撅級
+ const distributionRes = await getDeviceTypeDistribution({
startDate: dateRange.value ? dateRange.value[0] : null,
endDate: dateRange.value ? dateRange.value[1] : null,
- equipmentType: equipmentType.value
+ equipmentType: equipmentType.value,
+ year: selectedYear.value
});
- if (equipmentListRes.code === 200) {
- equipmentList.value = equipmentListRes.data.records;
- pagination.value.total = equipmentListRes.data.total;
-
- // 鏍规嵁 equipmentList 鎸� deviceName 杩涜鍒嗙被缁熻
- const deviceNameMap = {};
- equipmentList.value.forEach(item => {
- const deviceName = item.deviceName;
- if (!deviceNameMap[deviceName]) {
- deviceNameMap[deviceName] = {
- name: deviceName,
- count: 0,
- totalValue: 0
- };
- }
- deviceNameMap[deviceName].count += item.number || 1; // 鍋囪 number 涓鸿澶囨暟閲�
- deviceNameMap[deviceName].totalValue += item.taxIncludingPriceTotal || 0; // 绱姞鍚◣鎬讳环
- });
-
- // 杞崲涓� typeDistributionData 鏍煎紡
- typeDistributionData.value = Object.values(deviceNameMap).map(item => ({
- name: item.name,
- value: item.count,
- count: item.count,
- amount: `楼${formatCurrency(item.totalValue)}`
- }));
+ if (distributionRes.code === 200) {
+ const data = distributionRes.data;
+
+ // 鏇存柊璁惧绫诲瀷鎬绘暟
+ deviceTypeTotalCount.value = data.totalCount || 0;
+
+ // 杞崲楗煎浘鏁版嵁鏍煎紡
+ if (data.details && data.details.length > 0) {
+ typeDistributionData.value = data.details.map(item => ({
+ name: item.type || '',
+ value: Number(item.count || 0),
+ count: Number(item.count || 0),
+ amount: `楼${formatCurrency(item.amount || 0)}`
+ }));
+ } else if (data.categories && data.categories.length > 0) {
+ // 濡傛灉娌℃湁 details锛屼娇鐢� categories銆乧ountData 鍜� amountData 鏋勫缓
+ typeDistributionData.value = data.categories.map((category, index) => ({
+ name: category,
+ value: Number(data.countData[index] || 0),
+ count: Number(data.countData[index] || 0),
+ amount: `楼${formatCurrency(data.amountData[index] || 0)}`
+ }));
+ } else {
+ typeDistributionData.value = [];
+ }
// 鏇存柊x杞存暟鎹�
- xAxis.value[0].data = typeDistributionData.value.map(item => item.name);
+ xAxis.value[0].data = data.categories || typeDistributionData.value.map(item => item.name);
// 鏋勫缓鎶樼嚎鍥炬暟鎹�
typeDistributionLineSeries.value = [
{
name: '璁惧鏁伴噺',
type: 'line',
- data: typeDistributionData.value.map(item => item.count)
+ data: data.countData || typeDistributionData.value.map(item => item.count)
}
];
+ }
+
+ // 鑾峰彇璁惧鍒楄〃锛堟姌鏃ц绠楁暟鎹級
+ const equipmentListRes = await getCalculateDepreciation({
+ current: pagination.value.currentPage,
+ size: pagination.value.pageSize,
+ startDate: dateRange.value ? dateRange.value[0] : null,
+ endDate: dateRange.value ? dateRange.value[1] : null,
+ equipmentType: equipmentType.value,
+ year: selectedYear.value
+ });
+
+ if (equipmentListRes.code === 200) {
+ // 濡傛灉杩斿洖鐨勬槸鍒嗛〉鏁版嵁
+ if (equipmentListRes.data.records) {
+ equipmentList.value = equipmentListRes.data.records;
+ pagination.value.total = equipmentListRes.data.total;
+ } else if (Array.isArray(equipmentListRes.data)) {
+ // 濡傛灉杩斿洖鐨勬槸鏁扮粍
+ equipmentList.value = equipmentListRes.data;
+ pagination.value.total = equipmentListRes.data.length;
+ } else {
+ equipmentList.value = [];
+ pagination.value.total = 0;
+ }
}
} catch (error) {
console.error('鑾峰彇鍥哄畾璧勪骇鏁版嵁澶辫触锛�', error);
@@ -401,6 +461,7 @@
const resetFilters = () => {
dateRange.value = null;
equipmentType.value = '';
+ selectedYear.value = dayjs().format('YYYY'); // 閲嶇疆涓哄綋鍓嶅勾浠�
fetchData();
};
@@ -486,10 +547,10 @@
}
}
-/* 澶у睆骞曞強浠ヤ笂 (lg:grid-cols-5) */
+/* 澶у睆骞曞強浠ヤ笂 (lg:grid-cols-6) */
@media (min-width: 1024px) {
.grid-container {
- grid-template-columns: repeat(5, minmax(0, 1fr));
+ grid-template-columns: repeat(6, minmax(0, 1fr));
}
}
diff --git a/src/views/inventoryManagement/receiptManagement/components/formDia.vue b/src/views/inventoryManagement/receiptManagement/components/formDia.vue
new file mode 100644
index 0000000..5ea86b2
--- /dev/null
+++ b/src/views/inventoryManagement/receiptManagement/components/formDia.vue
@@ -0,0 +1,400 @@
+<template>
+ <el-dialog v-model="dialogFormVisible" :title="getDialogTitle()" width="70%"
+ @close="closeDia">
+ <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+ <el-form-item label="閲囪喘璁㈠崟鍙�" prop="purchaseContractNumber">
+ <el-select
+ v-model="form.purchaseContractNumber"
+ placeholder="璇烽�夋嫨閲囪喘璁㈠崟鍙�"
+ clearable
+ filterable
+ :loading="loadingPurchaseOptions"
+ @change="handlePurchaseChange"
+ :disabled="operationType === 'edit'"
+ style="width: 100%"
+ >
+ <el-option
+ v-for="item in purchaseOptions"
+ :key="item.purchaseContractNumber"
+ :label="formatPurchaseOption(item)"
+ :value="item.purchaseContractNumber"
+ />
+ </el-select>
+ </el-form-item>
+ <el-table
+ :data="productList"
+ border
+ v-loading="loadingProducts"
+ @selection-change="handleSelectionChange"
+ >
+ <el-table-column align="center" type="selection" width="55" />
+ <el-table-column
+ align="center"
+ label="搴忓彿"
+ type="index"
+ width="60"
+ />
+ <el-table-column label="浜у搧澶х被" prop="productCategory" />
+ <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
+ <el-table-column label="鍗曚綅" prop="unit" width="70" />
+ <!-- <el-table-column label="渚涘簲鍟�" prop="supplierName" width="100" /> -->
+ <el-table-column label="閲囪喘鏁伴噺" prop="quantity" width="100" />
+ <el-table-column label="寰呭叆搴撴暟閲�" prop="quantity0" width="100" />
+ <el-table-column label="鏈鍏ュ簱鏁伴噺" prop="quantityStock" width="150">
+ <template #default="scope">
+ <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.quantityStock" @change="() => calculateTotalPrice(scope.row)" />
+ </template>
+ </el-table-column>
+ <el-table-column label="绋庣巼(%)" prop="taxRate" width="120" />
+ <el-table-column label="鍗曚环(鍏�)" prop="taxInclusiveUnitPrice" width="150">
+ <template #default="scope">
+ <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.taxInclusiveUnitPrice" @change="() => calculateTotalPrice(scope.row)" :disabled="operationType === 'edit'"/>
+ </template>
+ </el-table-column>
+ <el-table-column
+ label="鎬讳环(鍏�)"
+ :formatter="formattedNumber"
+ prop="taxInclusiveTotalPrice"
+ width="150"
+ >
+ </el-table-column>
+ </el-table>
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitForm">纭</el-button>
+ <el-button @click="closeDia">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+</template>
+
+<script setup>
+import { ref, reactive, toRefs, getCurrentInstance } from 'vue'
+import useUserStore from '@/store/modules/user'
+import {
+ updateStockIn,
+ addSutockIn,
+ selectProductRecordListByPuechaserId
+} from "@/api/inventoryManagement/stockIn.js";
+import { purchaseListPage } from "@/api/procurementManagement/procurementLedger.js";
+
+const userStore = useUserStore()
+const { proxy } = getCurrentInstance()
+const emit = defineEmits(['close', 'success'])
+
+const operationType = ref('')// 鎿嶄綔绫诲瀷: 'add' 鎴� 'edit'
+const dialogFormVisible = ref(false)// 寮规鏄剧ず鐘舵��
+const productList = ref([]);// 浜у搧鍒楄〃鏁版嵁
+const loadingProducts = ref(false);// 浜у搧鍔犺浇鐘舵��
+const selectedRows = ref([]) // 浜у搧琛ㄦ牸閫変腑琛�
+const purchaseOptions = ref([])
+const loadingPurchaseOptions = ref(false)
+const loading = ref(false);
+
+const data = reactive({
+ form: {
+ id: null,
+ purchaseContractNumber: '', // 閲囪喘璁㈠崟鍙�
+ supplierId: null, // 渚涘簲鍟咺D
+ supplierName: '', // 渚涘簲鍟嗗悕绉�
+ inboundTime: '', // 鍏ュ簱鏃堕棿
+ inboundBatch: '', // 鍏ュ簱鎵规
+ recorderId: userStore.userId, // 褰曞叆浜篒D
+ recorderName: userStore.name, // 褰曞叆浜哄鍚�
+ entryDate: getCurrentDate(), // 褰曞叆鏃ユ湡
+ remark: '', // 澶囨敞
+ },
+ rules: {
+ purchaseContractNumber: [{ required: true, message: "璇疯緭鍏ラ噰璐悎鍚屽彿", trigger: "blur" }],
+ supplierId: [{ required: true, message: "璇烽�夋嫨渚涘簲鍟�", trigger: "change" }],
+ inboundTime: [{ required: true, message: "璇烽�夋嫨鍏ュ簱鏃堕棿", trigger: "change" }],
+ inboundBatch: [{ required: true, message: "璇疯緭鍏ュ叆搴撴壒娆�", trigger: "blur" }]
+ }
+})
+const { form, rules } = toRefs(data)
+
+// 鍔ㄦ�佽绠楀璇濇鏍囬
+const getDialogTitle = () => {
+ return operationType.value === 'add' ? '鏂板鍏ュ簱' : '缂栬緫鍏ュ簱'
+}
+
+const formatPurchaseOption = (item = {}) => {
+ const contract = item.purchaseContractNumber || '--';
+ const supplier = item.supplierName ? ` 路 ${item.supplierName}` : '';
+ return `${contract}${supplier}`;
+};
+
+const loadPurchaseOptions = async (keyword = '') => {
+ try {
+ loadingPurchaseOptions.value = true;
+ const res = await purchaseListPage({
+ current: -1,
+ size: -1,
+ purchaseContractNumber: keyword,
+ });
+ const records = res.data?.records || [];
+ purchaseOptions.value = records;
+ if (
+ form.value.purchaseContractNumber &&
+ !purchaseOptions.value.find(
+ (item) => item.purchaseContractNumber === form.value.purchaseContractNumber
+ )
+ ) {
+ purchaseOptions.value.push({
+ purchaseContractNumber: form.value.purchaseContractNumber,
+ supplierName: form.value.supplierName,
+ supplierId: form.value.supplierId,
+ });
+ }
+ } finally {
+ loadingPurchaseOptions.value = false;
+ }
+};
+
+const handlePurchaseChange = (value) => {
+ form.value.purchaseContractNumber = value || '';
+ const matched = purchaseOptions.value.find(
+ (item) => item.purchaseContractNumber === value
+ );
+ if (matched) {
+ form.value.supplierName = matched.supplierName || form.value.supplierName;
+ form.value.supplierId = matched.supplierId || form.value.supplierId;
+ }
+ if (!value) {
+ productList.value = [];
+ return;
+ }
+ fetchProductsByContract();
+};
+
+const exceedsAddLimit = (product) => {
+ const stock = Number(product?.quantityStock ?? 0);
+ const waiting = Number(product?.quantity0 ?? 0);
+ if (!Number.isFinite(stock) || !Number.isFinite(waiting)) {
+ return false;
+ }
+ return stock > waiting;
+};
+
+const exceedsEditLimit = (product) => {
+ const stock = Number(product?.quantityStock ?? 0);
+ const waiting = Number(product?.quantity0 ?? 0);
+ const original = Number(product?.originalQuantityStock ?? 0);
+ if (!Number.isFinite(stock) || !Number.isFinite(waiting) || !Number.isFinite(original)) {
+ return false;
+ }
+ return stock > waiting + original;
+};
+
+const formattedNumber = (row, column, cellValue) => {
+ return parseFloat(cellValue).toFixed(2);
+};
+
+// 璁$畻鎬讳环
+const calculateTotalPrice = (row) => {
+ const quantityStock = Number(row?.quantityStock ?? 0);
+ const taxInclusiveUnitPrice = Number(row?.taxInclusiveUnitPrice ?? 0);
+
+ if (Number.isFinite(quantityStock) && Number.isFinite(taxInclusiveUnitPrice)) {
+ row.taxInclusiveTotalPrice = quantityStock * taxInclusiveUnitPrice;
+ } else {
+ row.taxInclusiveTotalPrice = 0;
+ }
+};
+
+const fetchProductsByContract = async () => {
+ if (!form.value.purchaseContractNumber) {
+ proxy.$modal.msgWarning('璇烽�夋嫨鍚堝悓鍙�')
+ return
+ }
+ try {
+ loadingProducts.value = true
+ const productRes = await selectProductRecordListByPuechaserId({
+ purchaseContractNumber: form.value.purchaseContractNumber
+ });
+ if (!productRes.data || productRes.data.length === 0) {
+ proxy.$modal.msgWarning('璇ュ悎鍚屼笅娌℃湁浜у搧璁板綍')
+ productList.value = [];
+ return
+ }
+ productList.value = productRes.data.map(item => ({
+ ...item,
+ quantityStock: 0,
+ taxInclusiveUnitPrice: Number(item?.taxInclusiveUnitPrice ?? 0),
+ taxInclusiveTotalPrice: 0,
+ originalQuantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? 0),
+ }))
+ } catch (error) {
+ console.error('鏌ヨ浜у搧璁板綍澶辫触:', error)
+ proxy.$modal.msgError('鏌ヨ浜у搧璁板綍澶辫触')
+ productList.value = [];
+ } finally {
+ loadingProducts.value = false
+ }
+}
+
+const updatePro = async () => {
+ if (selectedRows.value.length === 0) {
+ proxy.$modal.msgWarning('璇峰厛閫夋嫨浜у搧');
+ return;
+ }
+ const target = selectedRows.value[0];
+ const stock = Number(target?.quantityStock ?? 0);
+ if (!Number.isFinite(stock) || stock <= 0) {
+ proxy.$modal.msgWarning('璇峰~鍐欐湁鏁堢殑鍏ュ簱鏁伴噺');
+ return;
+ }
+ if (exceedsEditLimit(target)) {
+ proxy.$modal.msgError('鏈鍏ュ簱鏁伴噺涓嶈兘瓒呰繃鍘熷叆搴撴暟閲忎笌寰呭叆搴撴暟閲忎箣鍜�');
+ return;
+ }
+ const stockInData = {
+ id: selectedRows.value[0].recordId,
+ quantityStock: Number(selectedRows.value[0].quantityStock),
+ };
+ await updateStockIn(stockInData)
+ proxy.$modal.msgSuccess('淇敼鍏ュ簱鎴愬姛')
+ closeDia()
+ emit('success')
+}
+
+const submitForm = async () => {
+ if (selectedRows.value.length === 0) {
+ proxy.$modal.msgWarning('璇峰厛閫夋嫨閲囪喘鍚堝悓骞堕�夋嫨浜у搧')
+ return
+ }
+ if(operationType.value !== 'add'){
+ await updatePro()
+ return
+ }
+ try {
+ await proxy.$refs.formRef.validate()
+ const invalidProducts = selectedRows.value.filter((product) => {
+ const stock = Number(product?.quantityStock ?? 0);
+ if (!Number.isFinite(stock) || stock <= 0) {
+ return true;
+ }
+ return exceedsAddLimit(product);
+ })
+
+ if (invalidProducts.length > 0) {
+ proxy.$modal.msgError('鏈鍏ュ簱鏁伴噺闇�澶т簬0锛屼笖涓嶈兘瓒呰繃寰呭叆搴撴暟閲�')
+ return
+ }
+
+ const stockInData = {
+ ...form.value,
+ inboundTime: formatDateTime(form.value.inboundTime),
+ nickName: userStore.nickName,
+ details: selectedRows.value.map(product => ({
+ id: product.id,
+ inboundQuantity: Number(product.quantityStock),
+ unitPrice: Number(product.taxInclusiveUnitPrice),
+ taxRate: Number(product.taxRate),
+ taxInclusiveTotalPrice: Number(product.taxInclusiveTotalPrice)
+ })),
+ };
+ loading.value = true
+ await addSutockIn(stockInData)
+
+ proxy.$modal.msgSuccess('鏂板鍏ュ簱鎴愬姛')
+ closeDia()
+ emit('success')
+
+ } catch (error) {
+ console.error('鎻愪氦澶辫触:', error)
+ if (!error.errors) {
+ proxy.$modal.msgError('鎿嶄綔澶辫触锛岃閲嶈瘯')
+ }
+ } finally {
+ loading.value = false
+ }
+}
+
+const closeDia = () => {
+ proxy.$refs.formRef.resetFields()
+ dialogFormVisible.value = false
+ emit('close')
+}
+
+const handleSelectionChange = (selection) => {
+ selectedRows.value = selection.filter(item => item.id);
+}
+
+function formatDateTime(date = new Date(), includeTime = true) {
+ const d = new Date(date);
+ const year = d.getFullYear();
+ const month = String(d.getMonth() + 1).padStart(2, '0');
+ const day = String(d.getDate()).padStart(2, '0');
+
+ if (!includeTime) {
+ return `${year}-${month}-${day}`;
+ }
+
+ const hours = String(d.getHours()).padStart(2, '0');
+ const minutes = String(d.getMinutes()).padStart(2, '0');
+ const seconds = String(d.getSeconds()).padStart(2, '0');
+
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+}
+
+function getCurrentDate() {
+ return formatDateTime(new Date(), false);
+}
+
+const openDialog = async (type, row) => {
+ operationType.value = type
+ dialogFormVisible.value = true
+ selectedRows.value = []
+ await loadPurchaseOptions();
+
+ if (type === 'add') {
+ form.value = {
+ id: null,
+ purchaseContractNumber: '',
+ supplierId: null,
+ supplierName: '',
+ inboundTime: '',
+ inboundBatch: '',
+ recorderId: userStore.userId,
+ recorderName: userStore.name,
+ entryDate: getCurrentDate(),
+ remark: ''
+ }
+ productList.value = []
+ } else {
+ form.value = JSON.parse(JSON.stringify(row))
+ try {
+ loadingProducts.value = true
+ const res = await selectProductRecordListByPuechaserId({
+ purchaseContractNumber: form.value.purchaseContractNumber,
+ id: row.id
+ });
+ productList.value = res.data.map(item => ({
+ ...item,
+ quantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0),
+ taxInclusiveUnitPrice: Number(item?.taxInclusiveUnitPrice ?? 0),
+ taxInclusiveTotalPrice: Number(item?.quantityStock ?? 0) * Number(item?.taxInclusiveUnitPrice ?? 0),
+ originalQuantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0),
+ }))
+ selectedRows.value = productList.value
+ } catch (error) {
+ console.error('鍔犺浇浜у搧澶辫触:', error)
+ proxy.$modal.msgError('鍔犺浇浜у搧澶辫触')
+ productList.value = []
+ } finally {
+ loadingProducts.value = false
+ }
+ }
+}
+
+defineExpose({
+ openDialog,
+})
+</script>
+
+<style scoped lang="scss"></style>
+
+
+
diff --git a/src/views/inventoryManagement/receiptManagement/components/formDiaProduct.vue b/src/views/inventoryManagement/receiptManagement/components/formDiaProduct.vue
new file mode 100644
index 0000000..6048e18
--- /dev/null
+++ b/src/views/inventoryManagement/receiptManagement/components/formDiaProduct.vue
@@ -0,0 +1,302 @@
+<template>
+ <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '鏂板鑷畾涔夊叆搴�' : '缂栬緫鑷畾涔夊叆搴�'" width="70%"
+ @close="closeDia">
+ <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+ <div style="margin-bottom: 10px;" v-if="operationType === 'add'">
+ <el-button type="primary" @click="addProductRow">鏂板</el-button>
+ </div>
+ <el-table
+ :data="productList"
+ border
+ v-loading="loadingProducts"
+ >
+ <el-table-column
+ align="center"
+ label="搴忓彿"
+ type="index"
+ width="60"
+ />
+ <el-table-column label="浜у搧澶х被" prop="productCategory" width="200">
+ <template #default="scope">
+ <el-input v-model="scope.row.productCategory" placeholder="璇疯緭鍏ヤ骇鍝佸ぇ绫�" />
+ </template>
+ </el-table-column>
+ <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" width="200">
+ <template #default="scope">
+ <el-input v-model="scope.row.specificationModel" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" />
+ </template>
+ </el-table-column>
+ <el-table-column label="鍗曚綅" prop="unit" width="100">
+ <template #default="scope">
+ <el-input v-model="scope.row.unit" placeholder="璇疯緭鍏ュ崟浣�" />
+ </template>
+ </el-table-column>
+ <el-table-column label="鍏ュ簱鏁伴噺" prop="inboundNum" width="150">
+ <template #default="scope">
+ <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.inboundNum" @change="() => calculateTotalPrice(scope.row)" />
+ </template>
+ </el-table-column>
+ <el-table-column label="鍏ュ簱鏃ユ湡" prop="inboundDate" width="180">
+ <template #default="scope">
+ <el-date-picker
+ v-model="scope.row.inboundDate"
+ type="date"
+ placeholder="璇烽�夋嫨鍏ュ簱鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ style="width: 100%"
+ />
+ </template>
+ </el-table-column>
+ <el-table-column label="鍗曚环(鍏�)" prop="unitPrice" width="150">
+ <template #default="scope">
+ <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.unitPrice" @change="() => calculateTotalPrice(scope.row)" />
+ </template>
+ </el-table-column>
+ <el-table-column
+ label="鎬讳环(鍏�)"
+ prop="totalPrice"
+ width="150"
+ >
+ </el-table-column>
+ <el-table-column label="鎿嶄綔" width="80" v-if="operationType === 'add'">
+ <template #default="scope">
+ <el-button type="danger" size="small" @click="removeProductRow(scope.$index)">鍒犻櫎</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitForm">纭</el-button>
+ <el-button @click="closeDia">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+</template>
+
+<script setup>
+import { ref, reactive, toRefs, getCurrentInstance } from 'vue'
+import useUserStore from '@/store/modules/user'
+import {
+ addStockInCustom, updateProduct
+} from "@/api/inventoryManagement/stockIn.js";
+
+const userStore = useUserStore()
+const { proxy } = getCurrentInstance()
+const emit = defineEmits(['close', 'success'])
+
+const operationType = ref('')// 鎿嶄綔绫诲瀷: 'add' 鎴� 'edit'
+const dialogFormVisible = ref(false)// 寮规鏄剧ず鐘舵��
+const productList = ref([]);// 浜у搧鍒楄〃鏁版嵁
+const loadingProducts = ref(false);// 浜у搧鍔犺浇鐘舵��
+const loading = ref(false);
+
+function formatDateTime(date = new Date(), includeTime = true) {
+ const d = new Date(date);
+ const year = d.getFullYear();
+ const month = String(d.getMonth() + 1).padStart(2, '0');
+ const day = String(d.getDate()).padStart(2, '0');
+
+ if (!includeTime) {
+ return `${year}-${month}-${day}`;
+ }
+
+ const hours = String(d.getHours()).padStart(2, '0');
+ const minutes = String(d.getMinutes()).padStart(2, '0');
+ const seconds = String(d.getSeconds()).padStart(2, '0');
+
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+}
+
+function getCurrentDate() {
+ return formatDateTime(new Date(), false);
+}
+
+const itemTypeOptions = [
+ { label: '鐗╂枡', value: '鐗╂枡' },
+ { label: '鍘熸枡', value: '鍘熸枡' },
+ { label: '鎴愬搧', value: '鎴愬搧' },
+ { label: '鍏朵粬', value: '鍏朵粬' },
+]
+
+const taxRateOptions = [
+ { label: '1', value: 1 },
+ { label: '6', value: 6 },
+ { label: '13', value: 13 },
+]
+
+const data = reactive({
+ form: {
+ id: null,
+ supplierId: null, // 渚涘簲鍟咺D
+ supplierName: '', // 渚涘簲鍟嗗悕绉�
+ recorderId: userStore.userId, // 褰曞叆浜篒D
+ recorderName: userStore.name, // 褰曞叆浜哄鍚�
+ entryDate: getCurrentDate(), // 褰曞叆鏃ユ湡
+ remark: '', // 澶囨敞
+ },
+ rules: {
+ supplierName: [{ required: true, message: "璇疯緭鍏ヤ緵搴斿晢鍚嶇О", trigger: "blur" }]
+ }
+})
+const { form, rules } = toRefs(data)
+
+// 鏂板浜у搧琛�
+const addProductRow = () => {
+ productList.value.push({
+ id: null,
+ productCategory: '',
+ specificationModel: '',
+ unit: '',
+ supplierName: form.value.supplierName || '',
+ itemType: '',
+ inboundNum: 0,
+ inboundDate: '',
+ quantityStock: 0,
+ unitPrice: 0,
+ totalPrice: 0,
+ taxRate: null,
+ taxExclusiveTotalPrice: 0,
+ });
+};
+
+// 鍒犻櫎浜у搧琛�
+const removeProductRow = (index) => {
+ productList.value.splice(index, 1);
+};
+
+// 璁$畻鎬讳环锛堟牴鎹暟閲忋�佸崟浠峰拰鍚◣鍗曚环锛�
+const calculateTotalPrice = (row) => {
+ // 璁$畻鏅�氭�讳环锛歩nboundNum * unitPrice
+ const quantity = Number(row.inboundNum || 0);
+ const unitPrice = Number(row.unitPrice || 0);
+ row.totalPrice = quantity * unitPrice;
+ calculateExclusivePrice(row);
+};
+
+// 璁$畻涓嶅惈绋庢�讳环锛堟牴鎹惈绋庢�讳环鍜岀◣鐜囷級
+const calculateExclusivePrice = (row) => {
+ const totalPrice = Number(row.totalPrice || 0);
+ const taxRate = Number(row.taxRate || 0);
+ row.taxExclusiveTotalPrice = totalPrice / (1 + taxRate / 100);
+};
+
+const submitForm = async () => {
+ try {
+ await proxy.$refs.formRef.validate()
+
+ if (!productList.value.length) {
+ proxy.$modal.msgError('璇疯嚦灏戞坊鍔犱竴鏉′骇鍝佹暟鎹�')
+ return
+ }
+
+ // 楠岃瘉鑷畾涔夋坊鍔犵殑鏁版嵁蹇呭~瀛楁
+ for (let i = 0; i < productList.value.length; i++) {
+ const product = productList.value[i];
+ if (!product.productCategory || !product.specificationModel || !product.unit) {
+ proxy.$modal.msgError(`绗�${i + 1}琛屼骇鍝佹暟鎹湭濉啓瀹屾暣锛堜骇鍝佸ぇ绫汇�佽鏍煎瀷鍙枫�佸崟浣嶄负蹇呭~锛塦)
+ return
+ }
+ if (!product.inboundDate) {
+ proxy.$modal.msgError(`绗�${i + 1}琛岃閫夋嫨鍏ュ簱鏃ユ湡`)
+ return
+ }
+ const stock = Number(product?.inboundNum ?? 0);
+ if (!Number.isFinite(stock) || stock <= 0) {
+ proxy.$modal.msgError(`绗�${i + 1}琛屾湰娆″叆搴撴暟閲忛渶澶т簬0`)
+ return
+ }
+ }
+
+ const payloadList = productList.value.map(product => ({
+ id: product.id ?? null,
+ inboundNum: Number(product.inboundNum),
+ productCategory: product.productCategory,
+ specificationModel: product.specificationModel,
+ unit: product.unit,
+ supplierName: product.supplierName || form.value.supplierName,
+ itemType: product.itemType,
+ inboundDate: formatDateTime(product.inboundDate, false),
+ taxRate: Number(product.taxRate || 0),
+ taxExclusiveTotalPrice: Number(product.taxExclusiveTotalPrice || 0),
+ unitPrice: Number(product.unitPrice || 0),
+ }));
+ loading.value = true
+ if (operationType.value === 'edit') {
+ const editPayload = payloadList[0]
+ await updateProduct(editPayload)
+ } else {
+ await addStockInCustom(payloadList)
+ }
+
+ proxy.$modal.msgSuccess(operationType.value === 'edit' ? '缂栬緫鑷畾涔夊叆搴撴垚鍔�' : '鏂板鑷畾涔夊叆搴撴垚鍔�')
+ closeDia()
+ emit('success')
+
+ } catch (error) {
+ console.error('鎻愪氦澶辫触:', error)
+ if (!error.errors) {
+ proxy.$modal.msgError('鎿嶄綔澶辫触锛岃閲嶈瘯')
+ }
+ } finally {
+ loading.value = false
+ }
+}
+
+const closeDia = () => {
+ proxy.$refs.formRef.resetFields()
+ dialogFormVisible.value = false
+ productList.value = []
+ emit('close')
+}
+
+const openDialog = async (type, row) => {
+ operationType.value = type
+ dialogFormVisible.value = true
+
+ if (type === 'add') {
+ form.value = {
+ id: null,
+ supplierId: null,
+ supplierName: '',
+ recorderId: userStore.userId,
+ recorderName: userStore.name,
+ entryDate: getCurrentDate(),
+ remark: ''
+ }
+ productList.value = []
+ } else {
+ // 缂栬緫妯″紡锛氬皢琛屾暟鎹~鍏呭埌琛ㄦ牸涓互鏀寔淇敼
+ form.value = {
+ id: row?.id ?? null,
+ supplierId: row?.supplierId ?? null,
+ supplierName: row?.supplierName ?? '',
+ recorderId: userStore.userId,
+ recorderName: userStore.name,
+ entryDate: getCurrentDate(),
+ remark: row?.remark ?? ''
+ }
+ productList.value = [{
+ id: row?.id ?? null,
+ productCategory: row?.productCategory ?? '',
+ specificationModel: row?.specificationModel ?? '',
+ unit: row?.unit ?? '',
+ supplierName: row?.supplierName ?? '',
+ itemType: row?.itemType ?? '',
+ inboundNum: Number(row?.inboundNum ?? row?.inboundQuantity ?? 0),
+ inboundDate: row?.inboundDate ?? row?.createTime ?? '',
+ taxRate: Number(row?.taxRate ?? 0),
+ unitPrice: Number(row?.unitPrice ?? 0),
+ taxExclusiveTotalPrice: Number(row?.taxExclusiveTotalPrice ?? 0),
+ }]
+ }
+}
+
+defineExpose({
+ openDialog,
+})
+</script>
+
+<style scoped lang="scss"></style>
+
diff --git a/src/views/inventoryManagement/receiptManagement/index.vue b/src/views/inventoryManagement/receiptManagement/index.vue
index 030b615..9aebae4 100644
--- a/src/views/inventoryManagement/receiptManagement/index.vue
+++ b/src/views/inventoryManagement/receiptManagement/index.vue
@@ -1,551 +1,538 @@
<template>
<div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">渚涘簲鍟嗗悕绉帮細</span>
- <el-input v-model="searchForm.supplierName" style="width: 240px" placeholder="璇疯緭鍏�" @change="handleQuery"
- clearable prefix-icon="Search" />
- <span class="search_title ml10">鍏ュ簱鏃ユ湡锛�</span>
- <el-date-picker
- v-model="searchForm.timeStr"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- @change="handleQuery"
- />
- <el-button type="primary" @click="handleQuery" style="margin-left: 10px">鎼滅储</el-button>
- </div>
- <div>
- <el-button type="primary" @click="openForm('add')">鏂板鍏ュ簱</el-button>
- <el-button @click="handleOut">瀵煎嚭</el-button>
- <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
- </div>
- </div>
- <div class="table_list">
- <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
- :expand-row-keys="expandedRowKeys" :row-key="row => row.id" show-summary style="width: 100%"
- :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)">
- <el-table-column align="center" type="selection" width="55" />
- <el-table-column align="center" label="搴忓彿" type="index" width="60" />
- <el-table-column label="鍏ュ簱鏃堕棿" prop="createTime" width="100" show-overflow-tooltip />
- <el-table-column label="鍏ュ簱鎵规" prop="inboundBatches" width="160" show-overflow-tooltip />
- <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" width="240" show-overflow-tooltip />
- <el-table-column label="浜у搧澶х被" prop="productCategory" width="100" show-overflow-tooltip />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" width="200" show-overflow-tooltip />
- <el-table-column label="鍗曚綅" prop="unit" width="70" show-overflow-tooltip />
- <el-table-column label="鍏ュ簱鏁伴噺" prop="inboundNum" width="90" show-overflow-tooltip />
- <el-table-column label="鍚◣鍗曚环" prop="taxInclusiveUnitPrice" width="100" show-overflow-tooltip />
- <el-table-column label="鍚◣鎬讳环" prop="taxInclusiveTotalPrice" width="100" show-overflow-tooltip />
- <el-table-column label="绋庣巼(%)" prop="taxRate" width="80" show-overflow-tooltip />
- <el-table-column label="涓嶅惈绋庢�讳环" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip />
- <el-table-column label="鍏ュ簱浜�" prop="createBy" width="80" show-overflow-tooltip />
- <el-table-column fixed="right" label="鎿嶄綔" min-width="60" align="center">
- <template #default="scope">
- <el-button link type="primary" size="small" @click="openForm('edit', scope.row);">缂栬緫</el-button>
- </template>
- </el-table-column>
- </el-table>
- <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper"
- :page="page.current" :limit="page.size" @pagination="paginationChange" />
- </div>
-
- <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '鏂板鍏ュ簱' : '缂栬緫鍏ュ簱'" width="70%"
- @close="closeDia">
- <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
- <el-form-item label="閲囪喘璁㈠崟鍙�" prop="purchaseContractNumber">
- <el-select
- v-model="form.purchaseContractNumber"
- placeholder="璇烽�夋嫨閲囪喘璁㈠崟鍙�"
- clearable
- filterable
- remote
- :remote-method="loadPurchaseOptions"
- :loading="loadingPurchaseOptions"
- @change="handlePurchaseChange"
- :disabled="operationType === 'edit'"
- style="width: 100%"
- >
- <el-option
- v-for="item in purchaseOptions"
- :key="item.purchaseContractNumber"
- :label="formatPurchaseOption(item)"
- :value="item.purchaseContractNumber"
- />
- </el-select>
- </el-form-item>
- <el-table
- :data="productList"
- border
- v-loading="loadingProducts"
- @selection-change="handleSelectionChange"
- >
- <el-table-column align="center" type="selection" width="55" />
- <el-table-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- />
- <el-table-column label="浜у搧澶х被" prop="productCategory" />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
- <el-table-column label="鍗曚綅" prop="unit" width="70" />
- <el-table-column label="渚涘簲鍟�" prop="supplierName" width="100" />
- <el-table-column label="閲囪喘鏁伴噺" prop="quantity" width="100" />
- <el-table-column label="寰呭叆搴撴暟閲�" prop="quantity0" width="100" />
- <el-table-column label="鏈鍏ュ簱鏁伴噺" prop="quantityStock" width="150">
- <template #default="scope">
- <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.quantityStock" />
- </template>
- </el-table-column>
- <el-table-column label="绋庣巼(%)" prop="taxRate" width="120" />
- <el-table-column
- label="鍚◣鍗曚环(鍏�)"
- prop="taxInclusiveUnitPrice"
- :formatter="formattedNumber"
- width="150"
- />
- <el-table-column
- label="鍚◣鎬讳环(鍏�)"
- prop="taxInclusiveTotalPrice"
- :formatter="formattedNumber"
- width="150"
- />
- <el-table-column
- label="涓嶅惈绋庢�讳环(鍏�)"
- prop="taxExclusiveTotalPrice"
- :formatter="formattedNumber"
- width="150"
- />
- </el-table>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitForm">纭</el-button>
- <el-button @click="closeDia">鍙栨秷</el-button>
+ <el-tabs v-model="activeTab"
+ @tab-change="handleTabChange">
+ <el-tab-pane label="鎴愬搧鍏ュ簱"
+ name="production">
+ <div class="search_form">
+ <div>
+ <span class="search_title ml10">鍏ュ簱鏃ユ湡锛�</span>
+ <el-date-picker v-model="searchForm.timeStr"
+ type="date"
+ placeholder="璇烽�夋嫨鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ clearable
+ @change="handleQuery"/>
+ <span class="search_title ml10">浜у搧澶х被锛�</span>
+ <el-input v-model="searchForm.productCategory"
+ style="width: 240px"
+ placeholder="璇疯緭鍏�"
+ clearable/>
+ <el-button type="primary"
+ @click="handleQuery"
+ style="margin-left: 10px">鎼滅储
+ </el-button>
+ </div>
+ <div>
+ <el-button @click="handleOut">瀵煎嚭</el-button>
+ <el-button type="danger"
+ plain
+ @click="handleDelete">鍒犻櫎
+ </el-button>
+ </div>
</div>
- </template>
- </el-dialog>
+ <div class="table_list">
+ <el-table :data="tableData"
+ border
+ v-loading="tableLoading"
+ @selection-change="handleSelectionChange"
+ :expand-row-keys="expandedRowKeys"
+ :row-key="row => row.id"
+ show-summary
+ style="width: 100%"
+ :summary-method="summarizeMainTable"
+ height="calc(100vh - 18.5em)">
+ <el-table-column align="center"
+ type="selection"
+ width="55"/>
+ <el-table-column align="center"
+ label="搴忓彿"
+ type="index"
+ width="60"/>
+ <el-table-column label="鍏ュ簱鏃堕棿"
+ prop="createTime"
+ show-overflow-tooltip/>
+ <el-table-column label="閿�鍞悎鍚屽彿"
+ prop="salesContractNo"
+ width="180"
+ show-overflow-tooltip/>
+ <el-table-column label="浜у搧澶х被"
+ prop="productCategory"
+ show-overflow-tooltip/>
+ <el-table-column label="瑙勬牸鍨嬪彿"
+ prop="specificationModel"
+ show-overflow-tooltip/>
+ <el-table-column label="鍗曚綅"
+ prop="unit"
+ width="70"
+ show-overflow-tooltip/>
+ <el-table-column label="鍏ュ簱鏁伴噺"
+ prop="inboundNum"
+ width="100"
+ show-overflow-tooltip/>
+ <el-table-column label="鍗曚环(鍏�)"
+ prop="unitPrice"
+ width="150"></el-table-column>
+ <el-table-column label="鎬讳环(鍏�)"
+ prop="totalPrice"
+ width="150"></el-table-column>
+ <!-- <el-table-column fixed="right"
+ label="鎿嶄綔"
+ min-width="60"
+ align="center">
+ <template #default="scope">
+ <el-button link
+ type="primary"
+ size="small"
+ @click="openForm('edit', scope.row, 'production');">缂栬緫</el-button>
+ </template>
+ </el-table-column> -->
+ </el-table>
+ <pagination v-show="total > 0"
+ :total="total"
+ layout="total, sizes, prev, pager, next, jumper"
+ :page="page.current"
+ :limit="page.size"
+ @pagination="paginationChange"/>
+ </div>
+ </el-tab-pane>
+ <el-tab-pane label="鍘熸枡鍏ュ簱"
+ name="purchase">
+ <div class="search_form">
+ <div>
+ <span class="search_title ml10">鍏ュ簱鏃ユ湡锛�</span>
+ <el-date-picker v-model="searchForm.timeStr"
+ type="date"
+ placeholder="璇烽�夋嫨鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ clearable
+ @change="handleQuery"/>
+ <span class="search_title ml10">浜у搧澶х被锛�</span>
+ <el-input v-model="searchForm.productCategory"
+ style="width: 240px"
+ placeholder="璇疯緭鍏�"
+ clearable/>
+ <el-button type="primary"
+ @click="handleQuery"
+ style="margin-left: 10px">鎼滅储
+ </el-button>
+ </div>
+ <div>
+ <el-button type="primary"
+ @click="openForm('add', 'purchase')">鏂板鍏ュ簱
+ </el-button>
+ <el-button @click="handleOut">瀵煎嚭</el-button>
+ <el-button type="danger"
+ plain
+ @click="handleDelete">鍒犻櫎
+ </el-button>
+ </div>
+ </div>
+ <div class="table_list">
+ <el-table :data="tableData"
+ border
+ v-loading="tableLoading"
+ @selection-change="handleSelectionChange"
+ :expand-row-keys="expandedRowKeys"
+ :row-key="row => row.id"
+ show-summary
+ style="width: 100%"
+ :summary-method="summarizeMainTable"
+ height="calc(100vh - 18.5em)">
+ <el-table-column align="center"
+ type="selection"
+ width="55"/>
+ <el-table-column align="center"
+ label="搴忓彿"
+ type="index"
+ width="60"/>
+ <el-table-column label="鍏ュ簱鏃堕棿"
+ prop="createTime"
+ width="100"
+ show-overflow-tooltip/>
+ <el-table-column label="閲囪喘鍚堝悓鍙�"
+ prop="purchaseContractNumber"
+ width="180"
+ show-overflow-tooltip/>
+ <el-table-column label="渚涘簲鍟嗗悕绉�"
+ prop="supplierName"
+ width="240"
+ show-overflow-tooltip/>
+ <el-table-column label="浜у搧澶х被"
+ prop="productCategory"
+ show-overflow-tooltip/>
+ <el-table-column label="瑙勬牸鍨嬪彿"
+ prop="specificationModel"
+ show-overflow-tooltip/>
+ <el-table-column label="鍗曚綅"
+ prop="unit"
+ width="70"
+ show-overflow-tooltip/>
+ <el-table-column label="鍏ュ簱鏁伴噺"
+ prop="inboundNum"
+ width="100"
+ show-overflow-tooltip/>
+ <el-table-column label="鍚◣鍗曚环(鍏�)"
+ prop="taxInclusiveUnitPrice"
+ width="150"></el-table-column>
+ <el-table-column label="鍚◣鎬讳环(鍏�)"
+ prop="taxInclusiveTotalPrice"
+ width="150"></el-table-column>
+ <el-table-column label="鍏ュ簱浜�"
+ prop="createBy"
+ width="80"
+ show-overflow-tooltip/>
+ <el-table-column fixed="right"
+ label="鎿嶄綔"
+ min-width="60"
+ align="center">
+ <template #default="scope">
+ <el-button link
+ :disabled="scope.row.type == 1"
+ type="primary"
+ size="small"
+ @click="openForm('edit', scope.row, 'purchase');">缂栬緫
+ </el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ <pagination v-show="total > 0"
+ :total="total"
+ layout="total, sizes, prev, pager, next, jumper"
+ :page="page.current"
+ :limit="page.size"
+ @pagination="paginationChange"/>
+ </div>
+ </el-tab-pane>
+ <el-tab-pane label="鐢熶骇鍏ュ簱"
+ name="product">
+ <div class="search_form">
+ <div>
+ <span class="search_title ml10">鍏ュ簱鏃ユ湡锛�</span>
+ <el-date-picker v-model="searchForm.timeStr"
+ type="date"
+ placeholder="璇烽�夋嫨鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ clearable
+ @change="handleQuery"/>
+ <span class="search_title ml10">浜у搧澶х被锛�</span>
+ <el-input v-model="searchForm.productCategory"
+ style="width: 240px"
+ placeholder="璇疯緭鍏�"
+ clearable/>
+ <el-button type="primary"
+ @click="handleQuery"
+ style="margin-left: 10px">鎼滅储
+ </el-button>
+ </div>
+ <div>
+ <el-button type="primary"
+ @click="openForm('add', 'purchase')">鏂板鍏ュ簱
+ </el-button>
+ <el-button @click="handleOut">瀵煎嚭</el-button>
+ <el-button type="danger"
+ plain
+ @click="handleDelete">鍒犻櫎
+ </el-button>
+ </div>
+ </div>
+ <div class="table_list">
+ <el-table :data="tableData"
+ border
+ v-loading="tableLoading"
+ @selection-change="handleSelectionChange"
+ :expand-row-keys="expandedRowKeys"
+ :row-key="row => row.id"
+ show-summary
+ style="width: 100%"
+ :summary-method="summarizeMainTable"
+ height="calc(100vh - 18.5em)">
+ <el-table-column align="center"
+ type="selection"
+ width="55"/>
+ <el-table-column align="center"
+ label="搴忓彿"
+ type="index"
+ width="60"/>
+ <el-table-column label="鍏ュ簱鏃堕棿"
+ prop="createTime"
+ width="100"
+ show-overflow-tooltip/>
+ <el-table-column label="浜у搧澶х被"
+ prop="productCategory"
+ show-overflow-tooltip/>
+ <el-table-column label="瑙勬牸鍨嬪彿"
+ prop="specificationModel"
+ show-overflow-tooltip/>
+ <el-table-column label="鍗曚綅"
+ prop="unit"
+ width="220"
+ show-overflow-tooltip/>
+ <el-table-column label="鍏ュ簱鏁伴噺"
+ prop="inboundNum"
+ width="220"
+ show-overflow-tooltip/>
+ <el-table-column label="鍏ュ簱浜�"
+ prop="createBy"
+ width="220"
+ show-overflow-tooltip/>
+ </el-table>
+ <pagination v-show="total > 0"
+ :total="total"
+ layout="total, sizes, prev, pager, next, jumper"
+ :page="page.current"
+ :limit="page.size"
+ @pagination="pageProductChange"/>
+ </div>
+ </el-tab-pane>
+ </el-tabs>
+ <form-dia ref="formDia"
+ @close="handleQuery"
+ @success="handleQuery"></form-dia>
+ <form-dia-product ref="formDiaProduct"
+ @close="handleQuery"
+ @success="handleQuery"></form-dia-product>
</div>
</template>
<script setup>
-import pagination from '@/components/PIMTable/Pagination.vue'
-import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue'
-import { ElMessageBox } from "element-plus";
-import useUserStore from '@/store/modules/user'
+import pagination from "@/components/PIMTable/Pagination.vue";
+import {
+ ref,
+ reactive,
+ toRefs,
+ onMounted,
+ getCurrentInstance,
+ nextTick,
+} from "vue";
+import {ElMessageBox} from "element-plus";
+import useUserStore from "@/store/modules/user";
+import dayjs from "dayjs";
import {
getStockInPage,
- updateStockIn,
- addSutockIn,
+ getStockInPageByProduction,
+ getStockInPageByProductProduction,
delStockIn,
- selectProductRecordListByPuechaserId
} from "@/api/inventoryManagement/stockIn.js";
-import { purchaseListPage } from "@/api/procurementManagement/procurementLedger.js";
-import { getCurrentDate } from "@/utils/index.js";
+import FormDia from "./components/formDia.vue";
+import FormDiaProduct from "./components/formDiaProduct.vue";
-const userStore = useUserStore()
-const { proxy } = getCurrentInstance()
+// 鑾峰彇褰撳墠鏃ユ湡
+function getCurrentDate() {
+ return dayjs().format("YYYY-MM-DD");
+}
-const tableData = ref([])
-const selectedRows = ref([])
-const userList = ref([])
+const {proxy} = getCurrentInstance();
-const purchaseOptions = ref([])
-const loadingPurchaseOptions = ref(false)
-
-
-const loading = ref(false);
-const tableLoading = ref(false)
+const tableData = ref([]);
+const selectedRows = ref([]);
+const tableLoading = ref(false);
+const formDia = ref();
+const formDiaProduct = ref();
+const activeTab = ref("production"); // 褰撳墠婵�娲荤殑 tab
const page = reactive({
current: 1,
size: 100,
-})
-const total = ref(0)
+});
+const total = ref(0);
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref('')// 鎿嶄綔绫诲瀷: 'add' 鎴� 'edit'
-const dialogFormVisible = ref(false)// 寮规鏄剧ず鐘舵��
-const productList = ref([]);// 浜у搧鍒楄〃鏁版嵁
-const loadingProducts = ref(false);// 浜у搧鍔犺浇鐘舵��
-const productSelectedRows = ref([]) // 浜у搧琛ㄦ牸閫変腑琛�
const data = reactive({
searchForm: {
- supplierName: '',
- timeStr: '',
+ supplierName: "",
+ customerName: "",
+ productCategory: "",
+ timeStr: "",
},
- form: {
- id: null,
- purchaseContractNumber: '', // 閲囪喘璁㈠崟鍙�
- supplierId: null, // 渚涘簲鍟咺D
- supplierName: '', // 渚涘簲鍟嗗悕绉�
- inboundTime: '', // 鍏ュ簱鏃堕棿
- inboundBatch: '', // 鍏ュ簱鎵规
- recorderId: userStore.userId, // 褰曞叆浜篒D
- recorderName: userStore.name, // 褰曞叆浜哄鍚�
- entryDate: getCurrentDate(), // 褰曞叆鏃ユ湡
- remark: '', // 澶囨敞
- },
- rules: {
- purchaseContractNumber: [{ required: true, message: "璇疯緭鍏ラ噰璐悎鍚屽彿", trigger: "blur" }],
- supplierId: [{ required: true, message: "璇烽�夋嫨渚涘簲鍟�", trigger: "change" }],
- inboundTime: [{ required: true, message: "璇烽�夋嫨鍏ュ簱鏃堕棿", trigger: "change" }],
- inboundBatch: [{ required: true, message: "璇疯緭鍏ュ叆搴撴壒娆�", trigger: "blur" }]
- }
-})
-const { searchForm, form, rules } = toRefs(data)
-
-const formatPurchaseOption = (item = {}) => {
- const contract = item.purchaseContractNumber || '--';
- const supplier = item.supplierName ? ` 路 ${item.supplierName}` : '';
- return `${contract}${supplier}`;
-};
-
-const loadPurchaseOptions = async (keyword = '') => {
- try {
- loadingPurchaseOptions.value = true;
- const res = await purchaseListPage({
- current: -1,
- size: -1,
- purchaseContractNumber: keyword,
- });
- const records = res.data?.records || [];
- purchaseOptions.value = records;
- if (
- form.value.purchaseContractNumber &&
- !purchaseOptions.value.find(
- (item) => item.purchaseContractNumber === form.value.purchaseContractNumber
- )
- ) {
- purchaseOptions.value.push({
- purchaseContractNumber: form.value.purchaseContractNumber,
- supplierName: form.value.supplierName,
- supplierId: form.value.supplierId,
- });
- }
- } finally {
- loadingPurchaseOptions.value = false;
- }
-};
-
-const handlePurchaseChange = (value) => {
- form.value.purchaseContractNumber = value || '';
- const matched = purchaseOptions.value.find(
- (item) => item.purchaseContractNumber === value
- );
- if (matched) {
- form.value.supplierName = matched.supplierName || form.value.supplierName;
- form.value.supplierId = matched.supplierId || form.value.supplierId;
- }
- if (!value) {
- productList.value = [];
- return;
- }
- fetchProductsByContract();
-};
-const exceedsAddLimit = (product) => {
- const stock = Number(product?.quantityStock ?? 0);
- const waiting = Number(product?.quantity0 ?? 0);
- if (!Number.isFinite(stock) || !Number.isFinite(waiting)) {
- return false;
- }
- return stock > waiting;
-};
-
-const exceedsEditLimit = (product) => {
- const stock = Number(product?.quantityStock ?? 0);
- const waiting = Number(product?.quantity0 ?? 0);
- const original = Number(product?.originalQuantityStock ?? 0);
- if (!Number.isFinite(stock) || !Number.isFinite(waiting) || !Number.isFinite(original)) {
- return false;
- }
- return stock > waiting + original;
-};
-const formattedNumber = (row, column, cellValue) => {
- return parseFloat(cellValue).toFixed(2);
-};
+});
+const {searchForm} = toRefs(data);
// 鏌ヨ鍒楄〃
/** 鎼滅储鎸夐挳鎿嶄綔 */
const handleQuery = () => {
- page.current = 1
- getList()
-}
-const paginationChange = (obj) => {
+ page.current = 1;
+ getList();
+};
+const paginationChange = obj => {
page.current = obj.page;
page.size = obj.limit;
- getList()
-}
+ getList();
+};
+const pageProductChange = obj => {
+ page.current = obj.page;
+ page.size = obj.limit;
+ getList();
+};
const getList = () => {
- tableLoading.value = true
- getStockInPage({ ...searchForm.value, ...page }).then(res => {
- tableLoading.value = false
- tableData.value = res.data.records
- total.value = res.data.total
- console.log('tableData:', tableData.value)
- }).catch(() => {
- tableLoading.value = false
- })
-}
+ tableLoading.value = true;
+ const params = {...page};
-
-// 璋冪敤selectProductRecordListByPuechaserId杩欎釜鏂规硶鏍规嵁鍚堝悓鏌ヨ鍒癷d锛屽啀璋冪敤getProductRecordByhetong杩欎釜鏂规硶鏍规嵁id鏌ヨ鍒颁骇鍝佽鍗曡褰�
-// 鏂板鏍规嵁鍚堝悓鍙锋煡璇骇鍝佽褰曠殑鏂规硶
-const fetchProductsByContract = async () =>
-{
- if (!form.value.purchaseContractNumber) {
- proxy.$modal.msgWarning('璇烽�夋嫨鍚堝悓鍙�')
- return
+ // 鏍规嵁涓嶅悓鐨� tab 绫诲瀷浼犻�掍笉鍚岀殑鏌ヨ鍙傛暟
+ if (activeTab.value === "production") {
+ params.customerName = searchForm.value.customerName;
+ params.timeStr = searchForm.value.timeStr;
+ } else {
+ params.supplierName = searchForm.value.supplierName;
+ params.timeStr = searchForm.value.timeStr;
}
- try {
- loadingProducts.value = true
- // 鏍规嵁鍚堝悓鏌ヨ浜у搧璁板綍
- const productRes = await selectProductRecordListByPuechaserId({
- purchaseContractNumber: form.value.purchaseContractNumber
- });
- console.log('productRes:', productRes)
- if (!productRes.data || productRes.data.length === 0) {
- proxy.$modal.msgWarning('璇ュ悎鍚屼笅娌℃湁浜у搧璁板綍')
- productList.value = [];
- return
- }
- // 澶勭悊浜у搧鏁版嵁锛屾坊鍔犳湰娆″叆搴撴暟閲忓瓧娈�
- productList.value = productRes.data.map(item => ({
- ...item,
- quantityStock: 0,
- originalQuantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? 0),
- }))
- } catch (error) {
- console.error('鏌ヨ浜у搧璁板綍澶辫触:', error)
- proxy.$modal.msgError('鏌ヨ浜у搧璁板綍澶辫触')
- productList.value = [];
- } finally {
- loadingProducts.value = false
- }
-}
+ params.productCategory = searchForm.value.productCategory;
+ if (activeTab.value === "product") {
+ getStockInPageByProductProduction(params)
+ .then(res => {
+ tableLoading.value = false;
+ tableData.value = res.data.records;
+ });
+ }else {
+ // 鏍规嵁涓嶅悓鐨� tab 绫诲瀷璋冪敤涓嶅悓鐨勬帴鍙�
+ const apiCall =
+ activeTab.value === "production"
+ ? getStockInPageByProduction(params)
+ : getStockInPage(params);
+
+ apiCall
+ .then(res => {
+ tableLoading.value = false;
+ tableData.value = res.data.records;
+
+ // 鍓嶇璁$畻鎬讳环锛氭�讳环 = unitPrice * inboundNum
+ tableData.value = tableData.value.map(item => {
+ // 浣跨敤鍏ュ簱鏁伴噺璁$畻鎬讳环
+ const inboundNum = Number(item.inboundNum) || 0;
+ const unitPrice = Number(item.unitPrice) || 0;
+ const taxInclusiveUnitPrice = Number(item.taxInclusiveUnitPrice) || 0;
+
+ // 鏍规嵁鏍囩椤电被鍨嬭绠椾笉鍚岀殑鎬讳环
+ if (activeTab.value === "production") {
+ // 鎴愬搧搴撳瓨锛氭�讳环 = unitPrice * 鍏ュ簱鏁伴噺
+ item.totalPrice = (unitPrice * inboundNum).toFixed(2);
+ } else {
+ // 鍘熸枡鍜屾潗鏂欏簱瀛橈細鍚◣鎬讳环 = taxInclusiveUnitPrice * 鍏ュ簱鏁伴噺
+ item.taxInclusiveTotalPrice = (
+ taxInclusiveUnitPrice * inboundNum
+ ).toFixed(2);
+ }
+
+ return item;
+ });
+
+ total.value = res.data.total;
+ })
+ .catch(() => {
+ tableLoading.value = false;
+ });
+ }
+
+};
+
+// 鍒囨崲 tab
+const handleTabChange = tabName => {
+ page.current = 1;
+ // 鍒囨崲 tab 鏃舵竻绌烘悳绱㈡潯浠�
+ searchForm.value.supplierName = "";
+ searchForm.value.customerName = "";
+ searchForm.value.timeStr = "";
+ searchForm.value.productCategory = "";
+ getList();
+};
// 鎵撳紑寮规
- const openForm = async (type, row) => {
- operationType.value = type
- dialogFormVisible.value = true
- selectedRows.value = []
- await loadPurchaseOptions();
-
- if (type === 'add') {
- // 鏂板鏃跺垵濮嬪寲琛ㄥ崟
- form.value = {
- id: null,
- purchaseContractNumber: '',
- supplierId: null,
- supplierName: '',
- inboundTime: '',
- inboundBatch: '',
- recorderId: userStore.userId,
- recorderName: userStore.name,
- entryDate: getCurrentDate(),
- remark: ''
- }
- productList.value = [] // 娓呯┖浜у搧鍒楄〃
+const openForm = async (type, row, tabType) => {
+ const currentTab = tabType || activeTab.value;
+ await nextTick(() => {
+ if (currentTab === "production") {
+ formDiaProduct.value?.openDialog(type, row);
} else {
- form.value = JSON.parse(JSON.stringify(row))
- try {
- loadingProducts.value = true
- // 鏍规嵁鍚堝悓鍙峰姞杞藉搴旂殑浜у搧鍒楄〃锛堝亣璁� getProductByContract 鏄彲鐢ㄦ帴鍙o級
- const res = await selectProductRecordListByPuechaserId({
- purchaseContractNumber: form.value.purchaseContractNumber,
- id: row.id
- });
- productList.value = res.data.map(item => ({
- ...item,
- quantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0),
- originalQuantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0),
- }))
- selectedRows.value = productList.value
- } catch (error) {
- console.error('鍔犺浇浜у搧澶辫触:', error)
- proxy.$modal.msgError('鍔犺浇浜у搧澶辫触')
- productList.value = []
- } finally {
- loadingProducts.value = false
- }
+ formDia.value?.openDialog(type, row);
}
- }
+ });
+};
- const updatePro = async () => {
- // 鍑嗗鎻愪氦鏁版嵁
- // 鍑嗗鎻愪氦鏁版嵁 - 淇敼涓哄悗绔渶瑕佺殑鏍煎紡
- if (selectedRows.value.length === 0) {
- proxy.$modal.msgWarning('璇峰厛閫夋嫨浜у搧');
- return;
- }
- const target = selectedRows.value[0];
- const stock = Number(target?.quantityStock ?? 0);
- if (!Number.isFinite(stock) || stock <= 0) {
- proxy.$modal.msgWarning('璇峰~鍐欐湁鏁堢殑鍏ュ簱鏁伴噺');
- return;
- }
- if (exceedsEditLimit(target)) {
- proxy.$modal.msgError('鏈鍏ュ簱鏁伴噺涓嶈兘瓒呰繃鍘熷叆搴撴暟閲忎笌寰呭叆搴撴暟閲忎箣鍜�');
- return;
- }
- const stockInData = {
- id: selectedRows.value[0].recordId,
- quantityStock: Number(selectedRows.value[0].quantityStock),// 浣跨敤鏂版牸寮忓寲鍑芥暟
- };
- await updateStockIn(stockInData)
- proxy.$modal.msgSuccess('淇敼鍏ュ簱鎴愬姛')
- closeDia()
- getList() // 鍒锋柊鍒楄〃
- }
-
-// 鎻愪氦琛ㄥ崟
- const submitForm = async () => {
- // 楠岃瘉鑷冲皯閫夋嫨浜嗕竴涓骇鍝�
- if (selectedRows.value.length === 0) {
- proxy.$modal.msgWarning('璇峰厛閫夋嫨閲囪喘鍚堝悓骞堕�夋嫨浜у搧')
- return
- }
- if(operationType.value !== 'add'){
- await updatePro()
- return
- }
- try {
- await proxy.$refs.formRef.validate()
- // 楠岃瘉鍏ュ簱鏁伴噺
- const invalidProducts = selectedRows.value.filter((product) => {
- const stock = Number(product?.quantityStock ?? 0);
- if (!Number.isFinite(stock) || stock <= 0) {
- return true;
- }
- return exceedsAddLimit(product);
- })
-
- if (invalidProducts.length > 0) {
- proxy.$modal.msgError('鏈鍏ュ簱鏁伴噺闇�澶т簬0锛屼笖涓嶈兘瓒呰繃寰呭叆搴撴暟閲�')
- return
- }
-
- // 鍑嗗鎻愪氦鏁版嵁 - 淇敼涓哄悗绔渶瑕佺殑鏍煎紡
- const stockInData = {
- // 鍏ュ簱鍗曞熀鏈俊鎭�
- ...form.value,
- inboundTime: formatDateTime(form.value.inboundTime),
- nickName: userStore.nickName,
- details: selectedRows.value.map(product => ({
- id: product.id,
- // id: product.salesLedgerProductId,
- inboundQuantity: Number(product.quantityStock)
- })),
- };
- // 璋冪敤API
- loading.value = true
- await addSutockIn(stockInData)
-
- proxy.$modal.msgSuccess('鏂板鍏ュ簱鎴愬姛')
- closeDia()
- getList() // 鍒锋柊鍒楄〃
-
- } catch (error) {
- console.error('鎻愪氦澶辫触:', error)
- if (!error.errors) {
- proxy.$modal.msgError('鎿嶄綔澶辫触锛岃閲嶈瘯')
- }
- } finally {
- loading.value = false
- }
- }
-
-// 鍏抽棴寮规
- const closeDia = () => {
- proxy.$refs.formRef.resetFields()
- dialogFormVisible.value = false
-
- }
// 琛ㄦ牸閫夋嫨鏁版嵁
- const handleSelectionChange = (selection) => {
- // 杩囨护鎺夊瓙鏁版嵁
- selectedRows.value = selection.filter(item => item.id);
- }
+const handleSelectionChange = selection => {
+ selectedRows.value = selection.filter(item => item.id);
+};
- const expandedRowKeys = ref([])
+const expandedRowKeys = ref([]);
// 涓昏〃鍚堣鏂规硶
- const summarizeMainTable = (param) => {
- return proxy.summarizeTable(param, ['contractAmount', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']);
- };
+const summarizeMainTable = param => {
+ return proxy.summarizeTable(param, [
+ "contractAmount",
+ "taxInclusiveTotalPrice",
+ "taxExclusiveTotalPrice",
+ ]);
+};
// 瀵煎嚭
- const handleOut = () => {
- ElMessageBox.confirm(
- '鏄惁纭瀵煎嚭锛�',
- '瀵煎嚭', {
- confirmButtonText: '纭',
- cancelButtonText: '鍙栨秷',
- type: 'warning',
- }
- ).then(() => {
- proxy.download("/stockin/export", {}, '鍏ュ簱鍙拌处.xlsx')
- }).catch(() => {
- proxy.$modal.msg("宸插彇娑�")
- })
- }
-// 鍒犻櫎
- const handleDelete = () => {
- let ids = []
- if (selectedRows.value.length > 0) {
- // 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
- const unauthorizedData = selectedRows.value.filter(item => item.createUser !== userStore.id);
- if (unauthorizedData.length > 0) {
- proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
- return;
- }
- ids = selectedRows.value.map(item => item.id);
- } else {
- proxy.$modal.msgWarning('璇烽�夋嫨鏁版嵁')
- return
- }
- ElMessageBox.confirm(
- '閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�',
- '瀵煎嚭', {
- confirmButtonText: '纭',
- cancelButtonText: '鍙栨秷',
- type: 'warning',
- }
- ).then(() => {
- delStockIn({ids:ids}).then(res => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛")
- getList()
- })
- }).catch(() => {
- proxy.$modal.msg("宸插彇娑�")
- })
- }
-
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-// 淇敼涓烘洿閫氱敤鐨勬棩鏈熸椂闂存牸寮忓寲鍑芥暟
-function formatDateTime(date = new Date(), includeTime = true) {
- const d = new Date(date);
- const year = d.getFullYear();
- const month = String(d.getMonth() + 1).padStart(2, '0');
- const day = String(d.getDate()).padStart(2, '0');
-
- if (!includeTime) {
- return `${year}-${month}-${day}`; // 淇濇寔鍘熸湁 getCurrentDate 鍔熻兘
- }
-
- // 鏂板鏃堕棿閮ㄥ垎鏍煎紡鍖�
- const hours = String(d.getHours()).padStart(2, '0');
- const minutes = String(d.getMinutes()).padStart(2, '0');
- const seconds = String(d.getSeconds()).padStart(2, '0');
-
- return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
-}
-
- onMounted(() => {
- getList()
+const handleOut = () => {
+ ElMessageBox.confirm("鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
})
+ .then(() => {
+ // 鏍规嵁涓嶅悓鐨� tab 绫诲瀷璋冪敤涓嶅悓鐨勫鍑烘帴鍙�
+ let exportUrl = "/stockin/export";
+ if (activeTab.value === "production") {
+ exportUrl = "/stockin/exportOne";
+ }
+ proxy.download(exportUrl, {}, "鍏ュ簱鍙拌处.xlsx");
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
+};
+
+// 鍒犻櫎
+const handleDelete = () => {
+ if (selectedRows.value.length === 0) {
+ proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+ return;
+ }
+ const ids = selectedRows.value.map(item => item.id);
+
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ // 鏍规嵁褰撳墠 tab 绫诲瀷閫夋嫨涓嶅悓鐨勫垹闄ゆ帴鍙e拰type鍙傛暟
+ let deleteApi, deleteParams;
+
+ if (activeTab.value === "production") {
+ // 鎴愬搧鍒犻櫎锛宼ype浼�2
+ deleteApi = delStockIn;
+ deleteParams = {ids, type: 2};
+ } else {
+ // 鍘熸枡鍒犻櫎锛宼ype浼�1
+ deleteApi = delStockIn;
+ deleteParams = {ids, type: 1};
+ }
+
+ deleteApi(deleteParams)
+ .then(() => {
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+ getList();
+ })
+ .catch(() => {
+ proxy.$modal.msgError("鍒犻櫎澶辫触");
+ });
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
+};
+
+onMounted(() => {
+ getList();
+});
</script>
<style scoped lang="scss"></style>
+
+
+
diff --git a/src/views/lavorissue/ledger/Form.vue b/src/views/lavorissue/ledger/Form.vue
index 7031957..785ef7a 100644
--- a/src/views/lavorissue/ledger/Form.vue
+++ b/src/views/lavorissue/ledger/Form.vue
@@ -73,12 +73,12 @@
import useFormData from "@/hooks/useFormData";
import {ref,onMounted} from "vue";
import useUserStore from "@/store/modules/user";
-import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js";
import {deepCopySameProperties} from '@/utils/util'
const userStore = useUserStore();
import {
getDept
} from "@/api/collaborativeApproval/approvalProcess.js";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
const { proxy } = getCurrentInstance();
@@ -112,8 +112,12 @@
issueDate: undefined,
});
const getPersonList = () => {
- getStaffOnJob().then(res => {
- personList.value = res.data
+ staffOnJobListPage({
+ current: -1,
+ size: -1,
+ staffState: 1
+ }).then(res => {
+ personList.value = res.data.records
})
};
const loadForm = (data) => {
diff --git a/src/views/personnelManagement/contractManagement/components/formDia.vue b/src/views/personnelManagement/contractManagement/components/formDia.vue
index 224fdbb..54b2ef9 100644
--- a/src/views/personnelManagement/contractManagement/components/formDia.vue
+++ b/src/views/personnelManagement/contractManagement/components/formDia.vue
@@ -19,23 +19,24 @@
</div>
</template>
</el-dialog>
+ <Files ref="filesDia"></Files>
</div>
</template>
<script setup>
import {ref} from "vue";
-import {staffOnJobInfo} from "@/api/personnelManagement/staffOnJob.js";
import {findStaffContractListPage} from "@/api/personnelManagement/staffContract.js";
+const Files = defineAsyncComponent(() => import( "@/views/personnelManagement/contractManagement/filesDia.vue"));
const { proxy } = getCurrentInstance()
const emit = defineEmits(['close'])
-
+const filesDia = ref()
const dialogFormVisible = ref(false);
const operationType = ref('')
const tableColumn = ref([
- // {
- // label: "鍚堝悓骞撮檺",
- // prop: "contractTerm",
- // },
+ {
+ label: "鍚堝悓骞撮檺",
+ prop: "contractTerm",
+ },
{
label: "鍚堝悓寮�濮嬫棩鏈�",
prop: "contractStartTime",
@@ -43,6 +44,22 @@
{
label: "鍚堝悓缁撴潫鏃ユ湡",
prop: "contractEndTime",
+ },
+ {
+ dataType: "action",
+ label: "鎿嶄綔",
+ align: "center",
+ fixed: 'right',
+ width: 120,
+ operation: [
+ {
+ name: "涓婁紶闄勪欢",
+ type: "text",
+ clickFun: (row) => {
+ filesDia.value.openDialog( row,'鍚堝悓')
+ },
+ }
+ ],
},
]);
const tableData = ref([]);
@@ -59,6 +76,11 @@
}
}
+const openUploadFile = (row) => {
+ filesDia.value.open = true
+ filesDia.value.row = row
+}
+
// 鍏抽棴寮规
const closeDia = () => {
dialogFormVisible.value = false;
diff --git a/src/views/personnelManagement/contractManagement/filesDia.vue b/src/views/personnelManagement/contractManagement/filesDia.vue
index f752496..c0c5ee9 100644
--- a/src/views/personnelManagement/contractManagement/filesDia.vue
+++ b/src/views/personnelManagement/contractManagement/filesDia.vue
@@ -30,16 +30,10 @@
:isSelection="true"
@selection-change="handleSelectionChange"
height="500"
+ @pagination="paginationSearch"
+ :total="page.total"
>
</PIMTable>
- <pagination
- style="margin: 10px 0"
- v-show="total > 0"
- @pagination="paginationSearch"
- :total="total"
- :page="page.current"
- :limit="page.size"
- />
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDia">鍙栨秷</el-button>
diff --git a/src/views/personnelManagement/contractManagement/index.vue b/src/views/personnelManagement/contractManagement/index.vue
index 76f1401..1d2aab7 100644
--- a/src/views/personnelManagement/contractManagement/index.vue
+++ b/src/views/personnelManagement/contractManagement/index.vue
@@ -266,7 +266,7 @@
type: "warning",
})
.then(() => {
- proxy.download("/staff/staffOnJob/export", {}, "鍚堝悓绠$悊.xlsx");
+ proxy.download("/staff/staffOnJob/export", {staffState: 1}, "鍚堝悓绠$悊.xlsx");
})
.catch(() => {
proxy.$modal.msg("宸插彇娑�");
diff --git a/src/views/personnelManagement/dimission/components/formDia.vue b/src/views/personnelManagement/dimission/components/formDia.vue
index 84808f8..2b8a7fd 100644
--- a/src/views/personnelManagement/dimission/components/formDia.vue
+++ b/src/views/personnelManagement/dimission/components/formDia.vue
@@ -12,101 +12,93 @@
<el-form :model="form" label-width="200px" label-position="left" :rules="rules" ref="formRef" style="margin-top: 20px">
<el-row :gutter="30">
<el-col :span="12">
- <el-form-item label="濮撳悕锛�" prop="staffName">
- <el-select v-model="form.staffName" placeholder="璇烽�夋嫨浜哄憳" style="width: 100%" @change="handleSelect">
+ <el-form-item label="濮撳悕锛�" prop="staffOnJobId">
+ <el-select v-model="form.staffOnJobId"
+ placeholder="璇烽�夋嫨浜哄憳"
+ style="width: 100%"
+ :disabled="operationType === 'edit'"
+ @change="handleSelect">
<el-option
v-for="item in personList"
:key="item.id"
:label="item.staffName"
- :value="item.staffName"
+ :value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="鍛樺伐缂栧彿锛�">
- {{ form.staffNo || '-' }}
+ {{ currentStaffRecord.staffNo || '-' }}
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
<el-form-item label="鎬у埆锛�">
- {{ form.sex || '-' }}
+ {{ currentStaffRecord.sex || '-' }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="鎴风睄浣忓潃锛�">
- {{ form.nativePlace || '-' }}
+ {{ currentStaffRecord.nativePlace || '-' }}
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
<el-form-item label="宀椾綅锛�">
- {{ form.postName || '-' }}
+ {{ currentStaffRecord.postName || '-' }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="鐜颁綇鍧�锛�">
- {{ form.adress || '-' }}
+ {{ currentStaffRecord.adress || '-' }}
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
<el-form-item label="绗竴瀛﹀巻锛�">
- {{ form.firstStudy || '-' }}
+ {{ currentStaffRecord.firstStudy || '-' }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="涓撲笟锛�">
- {{ form.profession || '-' }}
+ {{ currentStaffRecord.profession || '-' }}
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
<el-form-item label="骞撮緞锛�">
- {{ form.age || '-' }}
+ {{ currentStaffRecord.age || '-' }}
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
<el-form-item label="鑱旂郴鐢佃瘽锛�">
- {{ form.phone || '-' }}
+ {{ currentStaffRecord.phone || '-' }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="绱ф�ヨ仈绯讳汉锛�">
- {{ form.emergencyContact || '-' }}
+ {{ currentStaffRecord.emergencyContact || '-' }}
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
<el-form-item label="绱ф�ヨ仈绯讳汉鑱旂郴鐢佃瘽锛�">
- {{ form.emergencyContactPhone || '-' }}
+ {{ currentStaffRecord.emergencyContactPhone || '-' }}
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
- <el-form-item label="鍚堝悓寮�濮嬫棩鏈燂細">
- {{ form.contractStartTime || '-' }}
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍚堝悓缁撴潫鏃ユ湡锛�">
- {{ form.contractEndTime || '-' }}
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="绂昏亴鍘熷洜锛�" prop="dimissionReason">
- <el-select v-model="form.dimissionReason" placeholder="璇烽�夋嫨绂昏亴鍘熷洜" style="width: 100%" @change="handleSelectDimissionReason">
+ <el-form-item label="绂昏亴鍘熷洜锛�" prop="reason">
+ <el-select v-model="form.reason" placeholder="璇烽�夋嫨绂昏亴鍘熷洜" style="width: 100%" @change="handleSelectDimissionReason">
<el-option
v-for="(item, index) in dimissionReasonOptions"
:key="index"
@@ -117,11 +109,10 @@
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="澶囨敞锛�" prop="dimissionRemark" v-show="form.dimissionReason === 'other'">
+ <el-form-item label="澶囨敞锛�" prop="remark" v-if="form.reason === 'other'">
<el-input
- v-model="form.dimissionRemark"
+ v-model="form.remark"
type="textarea"
- v-show="form.dimissionReason === 'other'"
:rows="3"
placeholder="澶囨敞"
maxlength="500"
@@ -136,7 +127,7 @@
<!-- <el-col :span="12">-->
<!-- <div class="info-item">-->
<!-- <span class="info-label">绂昏亴鍘熷洜锛�</span>-->
-<!-- <el-select v-model="form.dimissionReason" placeholder="璇烽�夋嫨浜哄憳" style="width: 100%" @change="handleSelect">-->
+<!-- <el-select v-model="form.reason" placeholder="璇烽�夋嫨浜哄憳" style="width: 100%" @change="handleSelect">-->
<!-- <el-option-->
<!-- v-for="(item, index) in dimissionReasonOptions"-->
<!-- :key="index"-->
@@ -167,8 +158,8 @@
<script setup>
import {ref, reactive, toRefs, getCurrentInstance} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
-import { staffOnJobListPage } from "@/api/personnelManagement/staffOnJob.js";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
+import {createStaffLeave, updateStaffLeave} from "@/api/personnelManagement/staffLeave.js";
const { proxy } = getCurrentInstance()
const emit = defineEmits(['close'])
@@ -176,30 +167,13 @@
const operationType = ref('')
const data = reactive({
form: {
- staffNo: "",
- staffName: "",
- sex: "",
- nativePlace: "",
- postName: "",
- sysPostId: 0,
- adress: "",
- firstStudy: "",
- profession: "",
- age: 0,
- phone: "",
- emergencyContact: "",
- emergencyContactPhone: "",
- contractTerm: 0,
- contractStartTime: "",
- contractEndTime: "",
- dimissionDate: "",
- dimissionReason: "",
- dimissionRemark: "",
- staffState: "",
+ staffOnJobId: undefined,
+ reason: "",
+ remark: "",
},
rules: {
staffName: [{ required: true, message: "璇烽�夋嫨浜哄憳" }],
- dimissionReason: [{ required: true, message: "璇烽�夋嫨绂昏亴鍘熷洜"}],
+ reason: [{ required: true, message: "璇烽�夋嫨绂昏亴鍘熷洜"}],
},
dimissionReasonOptions: [
{label: '钖祫寰呴亣', value: 'salary'},
@@ -207,45 +181,51 @@
{label: '宸ヤ綔鐜', value: 'work_environment'},
{label: '涓汉鍘熷洜', value: 'personal_reason'},
{label: '鍏朵粬', value: 'other'},
- ]
+ ],
+ currentStaffRecord: {},
});
-const { form, rules, dimissionReasonOptions } = toRefs(data);
+const { form, rules, dimissionReasonOptions, currentStaffRecord } = toRefs(data);
// 鎵撳紑寮规
const openDialog = (type, row) => {
- getList()
operationType.value = type;
dialogFormVisible.value = true;
if (operationType.value === 'edit') {
- getStaffJoinInfo(row.id).then(res => {
- form.value = {...res.data}
- })
+ currentStaffRecord.value = row
+ form.value.staffOnJobId = row.staffOnJobId
+ form.value.reason = row.reason
+ form.value.remark = row.remark
+ personList.value = [
+ {
+ staffName: row.staffName,
+ id: row.staffOnJobId,
+ }
+ ]
+ } else {
+ getList()
}
}
const handleSelectDimissionReason = (val) => {
if (val === 'other') {
- form.value.dimissionRemark = ''
+ form.value.remark = ''
}
}
// 鎻愪氦浜у搧琛ㄥ崟
const submitForm = () => {
form.value.staffState = 0
- if (form.value.dimissionReason !== 'other') {
- form.value.dimissionRemark = ''
- }
- if (!form.value.sysPostId) {
- form.value.sysPostId = 0;
+ if (form.value.reason !== 'other') {
+ form.value.remark = ''
}
proxy.$refs["formRef"].validate(valid => {
if (valid) {
if (operationType.value === "add") {
- staffJoinAdd(form.value).then(res => {
+ createStaffLeave(form.value).then(res => {
proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
closeDia();
})
} else {
- staffJoinUpdate(form.value).then(res => {
+ updateStaffLeave(currentStaffRecord.value.id, form.value).then(res => {
proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
closeDia();
})
@@ -258,25 +238,9 @@
const closeDia = () => {
// 琛ㄥ崟宸叉敞閲婏紝鎵嬪姩閲嶇疆琛ㄥ崟鏁版嵁
form.value = {
- staffNo: "",
- staffName: "",
- sex: "",
- nativePlace: "",
- postName: "",
- sysPostId: 0,
- adress: "",
- firstStudy: "",
- profession: "",
- age: 0,
- phone: "",
- emergencyContact: "",
- emergencyContactPhone: "",
- contractTerm: 0,
- contractStartTime: "",
- contractEndTime: "",
- dimissionDate: "",
- dimissionReason: "",
- staffState: "",
+ staffOnJobId: undefined,
+ reason: "",
+ remark: "",
};
dialogFormVisible.value = false;
emit('close')
@@ -298,46 +262,11 @@
};
const handleSelect = (val) => {
- let obj = personList.value.find(item => item.staffName === val)
+ let obj = personList.value.find(item => item.id === val)
+ currentStaffRecord.value = {}
if (obj) {
- let {
- sex,
- phone,
- staffNo,
- nativePlace,
- postName,
- sysPostId,
- adress,
- firstStudy,
- profession,
- age,
- emergencyContact,
- emergencyContactPhone,
- contractTerm,
- contractStartTime,
- contractEndTime,
- staffName
- } = obj
// 淇濈暀绂昏亴鏃ユ湡鍜岀鑱屽師鍥狅紝鍙洿鏂板憳宸ヤ俊鎭�
- form.value = {
- ...form.value,
- sex,
- phone,
- staffNo,
- nativePlace,
- postName,
- sysPostId,
- adress,
- firstStudy,
- profession,
- age,
- emergencyContact,
- emergencyContactPhone,
- contractTerm,
- contractStartTime,
- contractEndTime,
- staffName
- }
+ currentStaffRecord.value = obj
}
}
defineExpose({
diff --git a/src/views/personnelManagement/dimission/index.vue b/src/views/personnelManagement/dimission/index.vue
index 27e6766..c6ed705 100644
--- a/src/views/personnelManagement/dimission/index.vue
+++ b/src/views/personnelManagement/dimission/index.vue
@@ -11,22 +11,6 @@
clearable
:prefix-icon="Search"
/>
- <span style="margin-left: 10px;" class="search_title">鍚堝悓寮�濮嬫棩鏈燂細</span>
- <el-date-picker
- v-model="searchForm.entryDateStart"
- type="date"
- placeholder="璇烽�夋嫨鍚堝悓寮�濮嬫棩鏈�"
- size="default"
- @change="(date) => handleDateChange(date,1)"
- />
- <span style="margin-left: 10px;" class="search_title">鍚堝悓缁撴潫鏃ユ湡锛�</span>
- <el-date-picker
- v-model="searchForm.entryDateEnd"
- type="date"
- placeholder="璇烽�夋嫨鍚堝悓缁撴潫鏃ユ湡"
- size="default"
- @change="(date) => handleDateChange(date,2)"
- />
<el-button type="primary" @click="handleQuery" style="margin-left: 10px"
>鎼滅储</el-button
>
@@ -58,9 +42,8 @@
import { Search } from "@element-plus/icons-vue";
import {onMounted, ref} from "vue";
import FormDia from "@/views/personnelManagement/dimission/components/formDia.vue";
-import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
+import {findStaffLeaveListPage, batchDeleteStaffLeaves} from "@/api/personnelManagement/staffLeave.js";
import {ElMessageBox} from "element-plus";
-import dayjs from "dayjs";
const data = reactive({
searchForm: {
@@ -109,6 +92,10 @@
prop: "nativePlace",
},
{
+ label: "閮ㄩ棬",
+ prop: "deptName",
+ },
+ {
label: "宀椾綅",
prop: "postName",
},
@@ -145,24 +132,11 @@
prop: "emergencyContactPhone",
width:150
},
- // {
- // label: "鍚堝悓骞撮檺",
- // prop: "contractTerm",
- // },
- {
- label: "鍚堝悓寮�濮嬫棩鏈�",
- prop: "contractStartTime",
- width: 120
- },
- {
- label: "鍚堝悓缁撴潫鏃ユ湡",
- prop: "contractEndTime",
- width: 120
- },
{
dataType: "action",
label: "鎿嶄綔",
align: "center",
+ fixed: 'right',
operation: [
{
name: "缂栬緫",
@@ -186,20 +160,6 @@
const { proxy } = getCurrentInstance()
-const handleDateChange = (value,type) => {
- searchForm.value.entryDateEnd = null
- searchForm.value.entryDateStart = null
- if(type === 1){
- if (value) {
- searchForm.value.entryDateStart = dayjs(value).format("YYYY-MM-DD");
- }
- }else{
- if (value) {
- searchForm.value.entryDateEnd = dayjs(value).format("YYYY-MM-DD");
- }
- }
- getList();
-};
// 鏌ヨ鍒楄〃
/** 鎼滅储鎸夐挳鎿嶄綔 */
const handleQuery = () => {
@@ -213,7 +173,7 @@
};
const getList = () => {
tableLoading.value = true;
- staffJoinListPage({...page, ...searchForm.value, staffState: 0}).then(res => {
+ findStaffLeaveListPage({...page, ...searchForm.value}).then(res => {
tableLoading.value = false;
tableData.value = res.data.records
page.total = res.data.total;
@@ -248,7 +208,7 @@
type: "warning",
})
.then(() => {
- staffJoinDel(ids).then((res) => {
+ batchDeleteStaffLeaves(ids).then((res) => {
proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
getList();
});
@@ -265,7 +225,7 @@
type: "warning",
})
.then(() => {
- proxy.download("/staff/staffJoinLeaveRecord/export", {staffState: 0}, "浜哄憳绂昏亴.xlsx");
+ proxy.download("/staff/staffLeave/export", {}, "浜哄憳绂昏亴.xlsx");
})
.catch(() => {
proxy.$modal.msg("宸插彇娑�");
diff --git a/src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue b/src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue
index 00e796c..06eee04 100644
--- a/src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue
+++ b/src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue
@@ -56,6 +56,25 @@
</el-row>
<el-row :gutter="30">
<el-col :span="12">
+ <el-form-item label="閮ㄩ棬锛�" prop="sysDeptId">
+ <el-tree-select
+ v-model="form.sysDeptId"
+ :data="deptOptions"
+ :props="{ value: 'id', label: 'label', children: 'children' }"
+ value-key="id"
+ placeholder="璇烽�夋嫨閮ㄩ棬"
+ check-strictly
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="骞撮緞锛�" prop="age">
+ <el-input-number v-model="form.age" :precision="0" :step="1" style="width: 100%"/>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
<el-form-item label="绗竴瀛﹀巻锛�" prop="firstStudy">
<el-input v-model="form.firstStudy" placeholder="璇疯緭鍏�" clearable/>
</el-form-item>
@@ -63,13 +82,6 @@
<el-col :span="12">
<el-form-item label="涓撲笟锛�" prop="profession">
<el-input v-model="form.profession" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="骞撮緞锛�" prop="age">
- <el-input-number v-model="form.age" :precision="0" :step="1" style="width: 100%"/>
</el-form-item>
</el-col>
</el-row>
@@ -140,9 +152,10 @@
<script setup>
import {ref, onMounted} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
import {findPostOptions} from "@/api/system/post.js";
+import {listDept} from "@/api/system/dept.js";
import {staffOnJobInfo, createStaffOnJob, updateStaffOnJob} from "@/api/personnelManagement/staffOnJob.js";
+import {deptTreeSelect} from "@/api/system/user.js";
const { proxy } = getCurrentInstance()
const emit = defineEmits(['close'])
@@ -168,6 +181,7 @@
contractEndTime: "",
staffState: "",
sysPostId: undefined,
+ sysDeptId: undefined,
},
rules: {
staffNo: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
@@ -187,8 +201,9 @@
contractEndTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
},
postOptions: [], // 宀椾綅閫夐」
+ deptOptions: [], // 閮ㄩ棬閫夐」
});
-const { form, rules, postOptions } = toRefs(data);
+const { form, rules, postOptions, deptOptions } = toRefs(data);
// 鎵撳紑寮规
const openDialog = (type, row) => {
@@ -211,6 +226,7 @@
}
onMounted(() => {
fetchPostOptions()
+ fetchDeptOptions()
})
const fetchPostOptions = () => {
@@ -218,6 +234,27 @@
postOptions.value = res.data
})
}
+
+// 鏌ヨ閮ㄩ棬鍒楄〃
+const fetchDeptOptions = () => {
+ deptTreeSelect().then(response => {
+ deptOptions.value = filterDisabledDept(JSON.parse(JSON.stringify(response.data)))
+ })
+}
+
+/** 杩囨护绂佺敤鐨勯儴闂� */
+function filterDisabledDept(deptList) {
+ return deptList.filter(dept => {
+ if (dept.disabled) {
+ return false
+ }
+ if (dept.children && dept.children.length) {
+ dept.children = filterDisabledDept(dept.children)
+ }
+ return true
+ })
+}
+
// 鎻愪氦浜у搧琛ㄥ崟
const submitForm = () => {
if (!form.value.sysPostId) {
diff --git a/src/views/personnelManagement/employeeRecord/components/RenewContract.vue b/src/views/personnelManagement/employeeRecord/components/RenewContract.vue
new file mode 100644
index 0000000..9c2acfc
--- /dev/null
+++ b/src/views/personnelManagement/employeeRecord/components/RenewContract.vue
@@ -0,0 +1,141 @@
+<template>
+ <el-dialog
+ v-model="isShow"
+ title="缁鍚堝悓"
+ width="800px"
+ @close="closeModal"
+ >
+ <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+ <el-form-item label="鍚堝悓寮�濮嬫棩鏈燂細" prop="contractStartTime">
+ <el-date-picker
+ v-model="form.contractStartTime"
+ type="date"
+ placeholder="璇烽�夋嫨鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ clearable
+ style="width: 100%"
+ @change="calculateContractTerm"
+ />
+ </el-form-item>
+ <el-form-item label="鍚堝悓缁撴潫鏃ユ湡锛�" prop="contractEndTime">
+ <el-date-picker
+ v-model="form.contractEndTime"
+ type="date"
+ placeholder="璇烽�夋嫨鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ clearable
+ style="width: 100%"
+ @change="calculateContractTerm"
+ />
+ </el-form-item>
+ <el-form-item label="鍚堝悓骞撮檺锛�" prop="contractTerm">
+ <el-input-number v-model="form.contractTerm" :precision="0" :step="1" style="width: 100%" :disabled="true"/>
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitForm">纭</el-button>
+ <el-button @click="closeModal">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+</template>
+
+<script setup>
+// 缁鍚堝悓
+import { renewContract } from "@/api/personnelManagement/staffOnJob.js";
+import {computed, getCurrentInstance,} from "vue";
+
+const emit = defineEmits(['update:visible', 'completed']);
+
+const data = reactive({
+ form: {
+ contractTerm: 0,
+ contractStartTime: "",
+ contractEndTime: "",
+ },
+ rules: {
+ contractTerm: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ contractStartTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ contractEndTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ }
+});
+const { form, rules } = toRefs(data);
+let { proxy } = getCurrentInstance()
+
+const props = defineProps({
+ id: {
+ type: Number,
+ default: 0,
+ },
+
+ visible: {
+ type: Boolean,
+ required: true,
+ },
+})
+
+const isShow = computed({
+ get() {
+ return props.visible;
+ },
+ set(val) {
+ emit('update:visible', val);
+ },
+});
+
+// 璁$畻鍚堝悓骞撮檺
+const calculateContractTerm = () => {
+ if (form.value.contractStartTime && form.value.contractEndTime) {
+ const startDate = new Date(form.value.contractStartTime);
+ const endDate = new Date(form.value.contractEndTime);
+
+ if (endDate > startDate) {
+ // 璁$畻骞翠唤宸�
+ const yearDiff = endDate.getFullYear() - startDate.getFullYear();
+ const monthDiff = endDate.getMonth() - startDate.getMonth();
+ const dayDiff = endDate.getDate() - startDate.getDate();
+
+ let years = yearDiff;
+
+ // 濡傛灉缁撴潫鏃ユ湡鐨勬湀鏃ュ皬浜庡紑濮嬫棩鏈熺殑鏈堟棩锛屽垯鍑忓幓1骞�
+ if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
+ years = yearDiff - 1;
+ }
+
+ form.value.contractTerm = Math.max(0, years);
+ } else {
+ form.value.contractTerm = 0;
+ }
+ } else {
+ form.value.contractTerm = 0;
+ }
+};
+
+const submitForm = () => {
+ proxy.$refs["formRef"].validate(valid => {
+ if (valid) {
+ renewContract(props.id, form.value).then(res => {
+ if (res.code === 200) {
+ proxy.$modal.msgSuccess("缁鍚堝悓鎴愬姛");
+ emit('completed');
+ closeModal();
+ }
+ })
+ }
+ })
+}
+
+// 鍏抽棴寮规
+const closeModal = () => {
+ // 閲嶇疆琛ㄥ崟鏁版嵁
+ form.value = {
+ contractTerm: 0,
+ contractStartTime: "",
+ contractEndTime: "",
+ };
+ isShow.value = false;
+};
+</script>
diff --git a/src/views/personnelManagement/employeeRecord/index.vue b/src/views/personnelManagement/employeeRecord/index.vue
index b8e48eb..19addfa 100644
--- a/src/views/personnelManagement/employeeRecord/index.vue
+++ b/src/views/personnelManagement/employeeRecord/index.vue
@@ -39,6 +39,12 @@
</div>
<show-form-dia ref="formDia" @close="handleQuery"></show-form-dia>
<new-or-edit-form-dia ref="formDiaNewOrEditFormDia" @close="handleQuery"></new-or-edit-form-dia>
+ <renew-contract
+ v-if="isShowRenewContractModal"
+ v-model:visible="isShowRenewContractModal"
+ :id="id"
+ @completed="handleQuery"
+ />
</div>
</template>
@@ -48,9 +54,9 @@
import {ElMessageBox} from "element-plus";
import {batchDeleteStaffOnJobs, staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
import dayjs from "dayjs";
-
const NewOrEditFormDia = defineAsyncComponent(() => import("@/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue"));
const ShowFormDia = defineAsyncComponent(() => import( "@/views/personnelManagement/employeeRecord/components/Show.vue"));
+const RenewContract = defineAsyncComponent(() => import( "@/views/personnelManagement/employeeRecord/components/RenewContract.vue"));
const data = reactive({
searchForm: {
@@ -61,6 +67,8 @@
},
});
const { searchForm } = toRefs(data);
+const isShowRenewContractModal = ref(false);
+const id = ref(0);
const tableColumn = ref([
{
label: "鐘舵��",
@@ -100,6 +108,10 @@
{
label: "鎴风睄浣忓潃",
prop: "nativePlace",
+ },
+ {
+ label: "閮ㄩ棬",
+ prop: "deptName",
},
{
label: "宀椾綅",
@@ -166,6 +178,15 @@
openFormNewOrEditFormDia("edit", row);
},
},
+ {
+ name: "缁鍚堝悓",
+ type: "text",
+ showHide: row => row.staffState === 1,
+ clickFun: (row) => {
+ isShowRenewContractModal.value = true;
+ id.value = row.id;
+ },
+ },
// {
// name: "璇︽儏",
// type: "text",
@@ -212,7 +233,7 @@
tableLoading.value = true;
const params = { ...searchForm.value, ...page };
params.entryDate = undefined
- staffOnJobListPage({...params, staffState: 1}).then(res => {
+ staffOnJobListPage({...params}).then(res => {
tableLoading.value = false;
tableData.value = res.data.records
page.total = res.data.total;
diff --git a/src/views/personnelManagement/onboarding/components/formDia.vue b/src/views/personnelManagement/onboarding/components/formDia.vue
deleted file mode 100644
index 7cd6ab6..0000000
--- a/src/views/personnelManagement/onboarding/components/formDia.vue
+++ /dev/null
@@ -1,281 +0,0 @@
-<template>
- <div>
- <el-dialog
- v-model="dialogFormVisible"
- :title="operationType === 'add' ? '鏂板鍏ヨ亴' : '缂栬緫浜哄憳'"
- width="70%"
- @close="closeDia"
- >
- <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍛樺伐缂栧彿锛�" prop="staffNo">
- <el-input v-model="form.staffNo" placeholder="璇疯緭鍏�" clearable :disabled="operationType !== 'add'"/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="濮撳悕锛�" prop="staffName">
- <el-input v-model="form.staffName" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鎬у埆锛�" prop="sex">
- <el-select v-model="form.sex">
- <el-option label="鐢�" value="鐢�" />
- <el-option label="濂�" value="濂�" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鎴风睄浣忓潃锛�" prop="nativePlace">
- <el-input v-model="form.nativePlace" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="宀椾綅锛�" prop="sysPostId">
- <el-select v-model="form.sysPostId" placeholder="璇烽�夋嫨宀椾綅" clearable>
- <el-option
- v-for="item in postOptions"
- :key="item.postId"
- :label="item.postName"
- :value="item.postId"
- :disabled="item.status === '1'"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鐜颁綇鍧�锛�" prop="adress">
- <el-input v-model="form.adress" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="绗竴瀛﹀巻锛�" prop="firstStudy">
- <el-input v-model="form.firstStudy" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="涓撲笟锛�" prop="profession">
- <el-input v-model="form.profession" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="骞撮緞锛�" prop="age">
- <el-input-number v-model="form.age" :precision="0" :step="1" style="width: 100%"/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鑱旂郴鐢佃瘽锛�" prop="phone">
- <el-input v-model="form.phone" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="绱ф�ヨ仈绯讳汉锛�" prop="emergencyContact">
- <el-input v-model="form.emergencyContact" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="绱ф�ヨ仈绯讳汉鑱旂郴鐢佃瘽锛�" prop="emergencyContactPhone">
- <el-input v-model="form.emergencyContactPhone" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍚堝悓骞撮檺锛�" prop="contractTerm">
- <el-input-number v-model="form.contractTerm" :precision="0" :step="1" style="width: 100%" :disabled="true"/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍚堝悓寮�濮嬫棩鏈燂細" prop="contractStartTime">
- <el-date-picker
- v-model="form.contractStartTime"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- style="width: 100%"
- @change="calculateContractTerm"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍚堝悓缁撴潫鏃ユ湡锛�" prop="contractEndTime">
- <el-date-picker
- v-model="form.contractEndTime"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- style="width: 100%"
- @change="calculateContractTerm"
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitForm">纭</el-button>
- <el-button @click="closeDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import {ref, onMounted} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
-import {findPostOptions} from "@/api/system/post.js";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const data = reactive({
- form: {
- staffNo: "",
- staffName: "",
- sex: "",
- nativePlace: "",
- postJob: "",
- adress: "",
- firstStudy: "",
- profession: "",
- age: 0,
- phone: "",
- emergencyContact: "",
- emergencyContactPhone: "",
- contractTerm: 0,
- contractStartTime: "",
- contractEndTime: "",
- staffState: "",
- sysPostId: undefined,
- },
- rules: {
- staffNo: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
- staffName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- sex: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- nativePlace: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- postJob: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- adress: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- firstStudy: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- profession: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- age: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- phone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- emergencyContact: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- emergencyContactPhone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- contractTerm: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- contractStartTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- contractEndTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- },
- postOptions: [], // 宀椾綅閫夐」
-});
-const { form, rules, postOptions } = toRefs(data);
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
- operationType.value = type;
- dialogFormVisible.value = true;
- if (operationType.value === 'edit') {
- getStaffJoinInfo(row.id).then(res => {
- form.value = {...res.data}
- if (form.value.sysPostId === 0) {
- form.value.sysPostId = undefined
- }
- // 缂栬緫鏃朵篃璁$畻涓�娆″悎鍚屽勾闄�
- calculateContractTerm();
- })
- } else {
- form.value.id = ''
- }
-
-}
-onMounted(() => {
- fetchPostOptions()
-})
-
-const fetchPostOptions = () => {
- findPostOptions().then(res => {
- postOptions.value = res.data
- })
-}
-// 鎻愪氦浜у搧琛ㄥ崟
-const submitForm = () => {
- if (!form.value.sysPostId) {
- form.value.sysPostId = 0;
- }
- proxy.$refs.formRef.validate(valid => {
- if (valid) {
- form.value.staffState = 1
- if (operationType.value === "add") {
- staffJoinAdd(form.value).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- })
- } else {
- staffJoinUpdate(form.value).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- })
- }
- }
- })
-}
-// 璁$畻鍚堝悓骞撮檺
-const calculateContractTerm = () => {
- if (form.value.contractStartTime && form.value.contractEndTime) {
- const startDate = new Date(form.value.contractStartTime);
- const endDate = new Date(form.value.contractEndTime);
-
- if (endDate > startDate) {
- // 璁$畻骞翠唤宸�
- const yearDiff = endDate.getFullYear() - startDate.getFullYear();
- const monthDiff = endDate.getMonth() - startDate.getMonth();
- const dayDiff = endDate.getDate() - startDate.getDate();
-
- let years = yearDiff;
-
- // 濡傛灉缁撴潫鏃ユ湡鐨勬湀鏃ュ皬浜庡紑濮嬫棩鏈熺殑鏈堟棩锛屽垯鍑忓幓1骞�
- if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
- years = yearDiff - 1;
- }
-
- form.value.contractTerm = Math.max(0, years);
- } else {
- form.value.contractTerm = 0;
- }
- } else {
- form.value.contractTerm = 0;
- }
-};
-
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
- emit('close')
-};
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/onboarding/components/formDiaXJHT.vue b/src/views/personnelManagement/onboarding/components/formDiaXJHT.vue
deleted file mode 100644
index fa0c9e6..0000000
--- a/src/views/personnelManagement/onboarding/components/formDiaXJHT.vue
+++ /dev/null
@@ -1,386 +0,0 @@
-<template>
- <div>
- <el-dialog
- v-model="dialogFormVisible"
- :title="operationType === 'add' ? '鏂板鍏ヨ亴' : '缂栬緫浜哄憳'"
- width="70%"
- @close="closeDia"
- >
- <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍛樺伐缂栧彿锛�" prop="staffNo">
- <el-input v-model="form.staffNo" placeholder="璇疯緭鍏�" clearable :disabled="operationType !== 'add'"/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="濮撳悕锛�" prop="staffName">
- <el-input v-model="form.staffName" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鎬у埆锛�" prop="sex">
- <el-select v-model="form.sex">
- <el-option label="鐢�" value="鐢�" />
- <el-option label="濂�" value="濂�" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鎴风睄浣忓潃锛�" prop="nativePlace">
- <el-input v-model="form.nativePlace" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="宀椾綅锛�" prop="postJob">
- <el-input v-model="form.postJob" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鐜颁綇鍧�锛�" prop="adress">
- <el-input v-model="form.adress" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="绗竴瀛﹀巻锛�" prop="firstStudy">
- <el-input v-model="form.firstStudy" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="涓撲笟锛�" prop="profession">
- <el-input v-model="form.profession" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="骞撮緞锛�" prop="age">
- <el-input-number v-model="form.age" :precision="0" :step="1" style="width: 100%"/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鑱旂郴鐢佃瘽锛�" prop="phone">
- <el-input v-model="form.phone" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="绱ф�ヨ仈绯讳汉锛�" prop="emergencyContact">
- <el-input v-model="form.emergencyContact" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="绱ф�ヨ仈绯讳汉鑱旂郴鐢佃瘽锛�" prop="emergencyContactPhone">
- <el-input v-model="form.emergencyContactPhone" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍚堝悓绛捐鏃ユ湡锛�" prop="trialStartDate">
- <el-date-picker
- v-model="form.trialStartDate"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="鍔冲姩鍚堝悓鏈熼檺閫夋嫨锛�" prop="dateSelect">
- <el-radio-group v-model="form.dateSelect">
- <el-radio :value="'A'">
- A銆佹湁鍥哄畾鏈熼檺
- </el-radio>
- <el-radio :value="'B'">
- B銆佹棤鍥哄畾鏈熼檺
- </el-radio>
- <el-radio :value="'C'">
- C銆佷互瀹屾垚涓�瀹氬伐浣滀换鍔′负鏈熼檺
- </el-radio>
- </el-radio-group>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30" v-if="showProbationDates">
- <el-col :span="12">
- <el-form-item label="璇曠敤鏈熷紑濮嬫棩鏈燂細" prop="signDate">
- <el-date-picker
- v-model="form.signDate"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="璇曠敤鏈熺粨鏉熸棩鏈燂細" prop="trialEndDate">
- <el-date-picker
- v-model="form.trialEndDate"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- </el-row>
-<!-- <el-row :gutter="30">-->
-<!-- <el-col :span="12">-->
-<!-- <el-form-item label="鍚堝悓骞撮檺锛�" prop="contractTerm">-->
-<!-- <el-input-number v-model="form.contractTerm" :precision="0" :step="1" style="width: 100%" :disabled="true"/>-->
-<!-- </el-form-item>-->
-<!-- </el-col>-->
-<!-- </el-row>-->
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍚堝悓寮�濮嬫棩鏈燂細" prop="contractStartTime">
- <el-date-picker
- v-model="form.contractStartTime"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12" v-if="showContractEnd">
- <el-form-item label="鍚堝悓缁撴潫鏃ユ湡锛�" prop="contractEndTime">
- <el-date-picker
- v-model="form.contractEndTime"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="璇曠敤鏈熷伐璧勶細" prop="proSalary">
- <el-input-number placeholder="璇疯緭鍏ヨ瘯鐢ㄦ湡宸ヨ祫" :precision="2"
- :step="100"
- :min="0" v-model="form.proSalary" style="width: 100%"/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="宸ヨ祫鎶ラ叕锛�" prop="salarySelect">
- <el-radio-group v-model="form.salarySelect" class="salary-radio-group">
- <el-radio :value="'A'" class="salary-radio-item">
- A銆佷箼鏂圭殑宸ヨ祫鎶ラ叕鎸夌収鐢叉柟渚濇硶鍒跺畾鐨勮绔犲埗搴︿腑鐨勫唴閮ㄥ伐璧勫垎閰嶅姙娉曠‘瀹氾紝鏍规嵁涔欐柟鐨勫伐浣滃矖浣嶇‘瀹氬叾姣忔湀宸ヨ祫銆�
- </el-radio>
- <el-radio :value="'B'" class="salary-radio-item">
- B銆佺敳鏂瑰涔欐柟瀹炶鍩烘湰宸ヨ祫鍜岀哗鏁堝伐璧勭浉缁撳悎鐨勫唴閮ㄥ伐璧勫垎閰嶅姙娉曪紝涔欐柟鐨勬敹鍏ュ寘鎷熀鏈伐璧勩�佽椁愩�佷氦閫氥�佺敓娲讳綇瀹跨瓑鍚勯」琛ュ姪锛屽鏈夊彉鍔ㄦ牴鎹唴閮ㄥ伐璧勫垎閰嶅姙娉曡皟鏁村叾宸ヨ祫锛涚哗鏁堝伐璧勬牴鎹箼鏂圭殑宸ヤ綔涓氱哗銆佸姵鍔ㄦ垚鏋滃拰瀹為檯璐$尞鎸夌収鍐呴儴鍒嗛厤鍔炴硶鑰冩牳纭畾銆�
- </el-radio>
- <el-radio :value="'C'" class="salary-radio-item">
- C銆佺敳鏂瑰疄琛岃浠跺伐璧勫埗锛屼互鐢叉柟鎺ュ埌璁㈠崟鍙婂叕鍙哥敓浜ц鍒掞紝鎸夌収瀹氶鍜岃浠跺崟浠凤紝鏍规嵁涔欐柟瀹屾垚鐨勪笟缁╋紝鎸夋椂瓒抽鏀粯涔欐柟鐨勫伐璧勬姤閰��
- </el-radio>
- </el-radio-group>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="绂忓埄寰呴亣锛�" prop="remark">
- <el-input v-model="form.remark" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitForm">纭</el-button>
- <el-button @click="closeDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import {ref, reactive, toRefs, getCurrentInstance, computed, watch} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const data = reactive({
- form: {
- staffNo: "",
- staffName: "",
- sex: "",
- nativePlace: "",
- postJob: "",
- adress: "",
- firstStudy: "",
- profession: "",
- age: 0,
- phone: "",
- emergencyContact: "",
- emergencyContactPhone: "",
- dateSelect: "",
- signDate: "",
- trialEndDate: "",
- proSalary: null,
- trialStartDate: "",
- salarySelect: "",
- // contractTerm: 0,
- contractStartTime: "",
- contractEndTime: "",
- staffState: "",
- },
- rules: {
- staffNo: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
- staffName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- sex: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- nativePlace: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- postJob: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- adress: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- firstStudy: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- profession: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- age: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- phone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- emergencyContact: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- remark: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
- dateSelect: [{ required: true, message: "璇烽�夋嫨鍔冲姩鍚堝悓鏈熼檺", trigger: "change" }],
- signDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- trialEndDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- trialStartDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- salarySelect: [{ required: true, message: "璇烽�夋嫨宸ヨ祫鎶ラ叕鏂瑰紡", trigger: "change" }],
- // contractTerm: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- contractStartTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- contractEndTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- },
-});
-const { form, rules } = toRefs(data);
-
-const showContractEnd = computed(() => form.value.dateSelect === "A");
-const showProbationDates = computed(() => form.value.dateSelect === "A" || form.value.dateSelect === "B");
-
-watch(() => form.value.dateSelect, (type) => {
- if (type !== "A") {
- form.value.contractEndTime = "";
- }
-
- if (type === "C") {
- form.value.signDate = "";
- form.value.trialEndDate = "";
- form.value.proSalary = null;
- }
-}, { immediate: true });
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
- operationType.value = type;
- dialogFormVisible.value = true;
- if (operationType.value === 'edit') {
- getStaffJoinInfo(row.id).then(res => {
- form.value = {...res.data}
- // 缂栬緫鏃朵篃璁$畻涓�娆″悎鍚屽勾闄�
- // calculateContractTerm();
- })
- }
-}
-// 鎻愪氦浜у搧琛ㄥ崟
-const submitForm = () => {
- proxy.$refs.formRef.validate(valid => {
- if (valid) {
- form.value.staffState = 1
- if (operationType.value === "add") {
- staffJoinAdd(form.value).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- })
- } else {
- staffJoinUpdate(form.value).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- })
- }
- }
- })
-}
-// 璁$畻鍚堝悓骞撮檺
-// const calculateContractTerm = () => {
-// if (form.value.contractStartTime && form.value.contractEndTime) {
-// const startDate = new Date(form.value.contractStartTime);
-// const endDate = new Date(form.value.contractEndTime);
-//
-// if (endDate > startDate) {
-// // 璁$畻骞翠唤宸�
-// const yearDiff = endDate.getFullYear() - startDate.getFullYear();
-// const monthDiff = endDate.getMonth() - startDate.getMonth();
-// const dayDiff = endDate.getDate() - startDate.getDate();
-//
-// let years = yearDiff;
-//
-// // 濡傛灉缁撴潫鏃ユ湡鐨勬湀鏃ュ皬浜庡紑濮嬫棩鏈熺殑鏈堟棩锛屽垯鍑忓幓1骞�
-// if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
-// years = yearDiff - 1;
-// }
-//
-// form.value.contractTerm = Math.max(0, years);
-// } else {
-// form.value.contractTerm = 0;
-// }
-// } else {
-// form.value.contractTerm = 0;
-// }
-// };
-
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
- emit('close')
-};
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-.salary-radio-group {
- display: flex;
- gap: 12px;
-}
-
-.salary-radio-item {
- white-space: normal;
- word-wrap: break-word;
- line-height: 1.6;
- align-items: flex-start;
-}
-
-.salary-radio-item :deep(.el-radio__label) {
- white-space: normal;
- word-wrap: break-word;
- line-height: 1.6;
- padding-left: 8px;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/onboarding/index.vue b/src/views/personnelManagement/onboarding/index.vue
deleted file mode 100644
index edf4fa3..0000000
--- a/src/views/personnelManagement/onboarding/index.vue
+++ /dev/null
@@ -1,280 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">濮撳悕锛�</span>
- <el-input
- v-model="searchForm.staffName"
- style="width: 240px"
- placeholder="璇疯緭鍏ュ鍚嶆悳绱�"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- <span style="margin-left: 10px;" class="search_title">鍚堝悓寮�濮嬫棩鏈燂細</span>
- <el-date-picker
- v-model="searchForm.entryDateStart"
- type="date"
- placeholder="璇烽�夋嫨鍚堝悓寮�濮嬫棩鏈�"
- size="default"
- @change="(date) => handleDateChange(date,1)"
- />
- <span style="margin-left: 10px;" class="search_title">鍚堝悓缁撴潫鏃ユ湡锛�</span>
- <el-date-picker
- v-model="searchForm.entryDateEnd"
- type="date"
- placeholder="璇烽�夋嫨鍚堝悓缁撴潫鏃ユ湡"
- size="default"
- @change="(date) => handleDateChange(date,2)"
- />
- <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
- >鎼滅储</el-button
- >
- </div>
- <div>
- <el-button type="primary" @click="openForm('add')">鏂板鍏ヨ亴</el-button>
- <el-button @click="handleOut">瀵煎嚭</el-button>
- <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
- </div>
- </div>
- <div class="table_list">
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :page="page"
- :isSelection="true"
- @selection-change="handleSelectionChange"
- :tableLoading="tableLoading"
- @pagination="pagination"
- :total="page.total"
- ></PIMTable>
- </div>
- <form-dia ref="formDia" @close="handleQuery"></form-dia>
- </div>
-</template>
-
-<script setup>
-import { Search } from "@element-plus/icons-vue";
-import {onMounted, ref} from "vue";
-import FormDia from "@/views/personnelManagement/onboarding/components/formDia.vue";
-// import FormDia from "@/views/personnelManagement/onboarding/components/formDiaXJHT.vue"; // 鏂扮枂椋熷搧鍏徃鐢ㄧ殑琛ㄥ崟
-import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
-import {ElMessageBox} from "element-plus";
-import dayjs from "dayjs";
-
-const data = reactive({
- searchForm: {
- staffName: "",
- },
-});
-const { searchForm } = toRefs(data);
-const tableColumn = ref([
- {
- label: "鐘舵��",
- prop: "staffState",
- dataType: "tag",
- formatData: (params) => {
- if (params == 0) {
- return "绂昏亴";
- } else if (params == 1) {
- return "鍏ヨ亴";
- } else {
- return null;
- }
- },
- formatType: (params) => {
- if (params == 0) {
- return "danger";
- } else if (params == 1) {
- return "primary";
- } else {
- return null;
- }
- },
- },
- {
- label: "鍛樺伐缂栧彿",
- prop: "staffNo",
- },
- {
- label: "濮撳悕",
- prop: "staffName",
- },
- {
- label: "鎬у埆",
- prop: "sex",
- },
- {
- label: "鎴风睄浣忓潃",
- prop: "nativePlace",
- },
- {
- label: "宀椾綅",
- prop: "postName",
- },
- {
- label: "鐜颁綇鍧�",
- prop: "adress",
- width:200
- },
- {
- label: "绗竴瀛﹀巻",
- prop: "firstStudy",
- },
- {
- label: "涓撲笟",
- prop: "profession",
- width:100
- },
- {
- label: "骞撮緞",
- prop: "age",
- },
- {
- label: "鑱旂郴鐢佃瘽",
- prop: "phone",
- width:150
- },
- {
- label: "绱ф�ヨ仈绯讳汉",
- prop: "emergencyContact",
- width: 120
- },
- {
- label: "鑱旂郴鐢佃瘽",
- prop: "emergencyContactPhone",
- width:150
- },
- // {
- // label: "鍚堝悓骞撮檺",
- // prop: "contractTerm",
- // },
- {
- label: "鍚堝悓寮�濮嬫棩鏈�",
- prop: "contractStartTime",
- width: 120
- },
- {
- label: "鍚堝悓缁撴潫鏃ユ湡",
- prop: "contractEndTime",
- width: 120
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- fixed: 'right',
- operation: [
- {
- name: "缂栬緫",
- type: "text",
- clickFun: (row) => {
- openForm("edit", row);
- },
- },
- ],
- },
-]);
-const tableData = ref([]);
-const selectedRows = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
- total: 0,
-});
-const formDia = ref()
-const { proxy } = getCurrentInstance()
-
-const handleDateChange = (value,type) => {
- searchForm.value.entryDateEnd = null
- searchForm.value.entryDateStart = null
- if(type === 1){
- if (value) {
- searchForm.value.entryDateStart = dayjs(value).format("YYYY-MM-DD");
- }
- }else{
- if (value) {
- searchForm.value.entryDateEnd = dayjs(value).format("YYYY-MM-DD");
- }
- }
- getList();
-};
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- staffJoinListPage({...page, ...searchForm.value, staffState: 1}).then(res => {
- tableLoading.value = false;
- tableData.value = res.data.records
- page.total = res.data.total;
- }).catch(err => {
- tableLoading.value = false;
- })
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-// 鎵撳紑寮规
-const openForm = (type, row) => {
- nextTick(() => {
- formDia.value?.openDialog(type, row)
- })
-};
-
-// 鍒犻櫎
-const handleDelete = () => {
- let ids = [];
- if (selectedRows.value.length > 0) {
- ids = selectedRows.value.map((item) => item.id);
- } else {
- proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
- return;
- }
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- staffJoinDel(ids).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/staff/staffJoinLeaveRecord/export", {staffState: 1}, "浜哄憳鍏ヨ亴.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped></style>
diff --git a/src/views/personnelManagement/payrollManagement/components/formDia.vue b/src/views/personnelManagement/payrollManagement/components/formDia.vue
index e4cf0b3..cf93559 100644
--- a/src/views/personnelManagement/payrollManagement/components/formDia.vue
+++ b/src/views/personnelManagement/payrollManagement/components/formDia.vue
@@ -168,8 +168,8 @@
<script setup>
import {ref} from "vue";
-import {getStaffJoinInfo, getStaffOnJob, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
import {compensationAdd, compensationUpdate} from "@/api/personnelManagement/payrollManagement.js";
+import {staffOnJobInfo, staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
const { proxy } = getCurrentInstance()
const emit = defineEmits(['close'])
@@ -234,12 +234,16 @@
const openDialog = (type, row) => {
operationType.value = type;
dialogFormVisible.value = true;
- getStaffOnJob().then(res => {
- personList.value = res.data
- })
+ staffOnJobListPage({
+ current: -1,
+ size: -1,
+ staffState: 1
+ }).then(res => {
+ personList.value = res.data.records || []
+ })
form.value = {}
if (operationType.value === 'edit') {
- getStaffJoinInfo(row.id).then(res => {
+ staffOnJobInfo(row.staffId).then(res => {
form.value = {...row}
form.value.payDate = form.value.payDate + '-01'
})
diff --git a/src/views/personnelManagement/payrollManagement/index.vue b/src/views/personnelManagement/payrollManagement/index.vue
index 24e3dd8..f17f42e 100644
--- a/src/views/personnelManagement/payrollManagement/index.vue
+++ b/src/views/personnelManagement/payrollManagement/index.vue
@@ -53,7 +53,6 @@
import { Search } from "@element-plus/icons-vue";
import {onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue";
import FormDia from "@/views/personnelManagement/payrollManagement/components/formDia.vue";
-import {staffJoinDel} from "@/api/personnelManagement/onboarding.js";
import {ElMessageBox} from "element-plus";
import dayjs from "dayjs";
import {compensationDelete, compensationListPage} from "@/api/personnelManagement/payrollManagement.js";
diff --git a/src/views/personnelManagement/scheduling/index.vue b/src/views/personnelManagement/scheduling/index.vue
index 251dbe9..19d2062 100644
--- a/src/views/personnelManagement/scheduling/index.vue
+++ b/src/views/personnelManagement/scheduling/index.vue
@@ -253,9 +253,9 @@
import {useDict} from "@/utils/dict.js"
import {Plus, Download, Search, Refresh} from '@element-plus/icons-vue'
import {save, del, delByIds, listPage} from "@/api/personnelManagement/scheduling.js"
-import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js";
import dayjs from "dayjs";
import pagination from "@/components/PIMTable/Pagination.vue";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
const { proxy } = getCurrentInstance();
@@ -317,8 +317,12 @@
* 鑾峰彇褰撳墠鍦ㄨ亴浜哄憳鍒楄〃
*/
const getPersonList = () => {
- getStaffOnJob().then(res => {
- personList.value = res.data
+ staffOnJobListPage({
+ current: -1,
+ size: -1,
+ staffState: 1
+ }).then(res => {
+ personList.value = res.data.records || []
})
};
const paginationChange = (obj) => {
diff --git a/src/views/personnelManagement/selfService/index.vue b/src/views/personnelManagement/selfService/index.vue
index ca683c0..647f149 100644
--- a/src/views/personnelManagement/selfService/index.vue
+++ b/src/views/personnelManagement/selfService/index.vue
@@ -221,8 +221,7 @@
const { proxy } = getCurrentInstance()
import { getUserProfile } from '@/api/system/user.js'
-import {staffJoinUpdate, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
-import { fa, id } from 'element-plus/es/locales.mjs'
+import {staffOnJobListPage, updateStaffOnJob} from "@/api/personnelManagement/staffOnJob.js";
const tableLoading = ref(false)
// 鍒嗛〉鍙傛暟
@@ -572,7 +571,7 @@
currentUser.value = res.data
// console.log("----",currentUser.value)
//寰楀埌浜哄憳鍒楄〃
- staffJoinListPage({staffState: 1}).then(res => {
+ staffOnJobListPage({staffState: 1}).then(res => {
//绛涢�夊嚭鍜宑urrentUser鍚屽悕鐨勪汉鍛�
// let tableData = res.data.records
user.value = res.data.records.find(item => item.staffName === currentUser.value.userName)
@@ -604,18 +603,15 @@
const userRes = await getUserProfile();
if (userRes.code === 200) {
currentUser.value = userRes.data;
- const staffListRes = await staffJoinListPage({ staffState: 1 });
+ const staffListRes = await staffOnJobListPage({ staffState: 1 });
user.value = staffListRes.data.records.find(item => item.staffName === currentUser.value.userName);
- // console.log("++++", user.value);
-
Object.assign(joinForm, user.value);
joinForm.staffName = profileForm.name;
joinForm.phone = profileForm.phone;
joinForm.email = profileForm.email;
joinForm.adress = profileForm.adress;
- console.log(joinForm)
// 璋冪敤鏇存柊涓汉淇℃伅鐨勬帴鍙�
- staffJoinUpdate(joinForm).then(res => {
+ updateStaffOnJob(user.value.id, joinForm).then(res => {
if (res.code === 200) {
ElMessage.success('涓汉淇℃伅淇濆瓨鎴愬姛');
getProfile();
diff --git a/src/views/procurementManagement/procurementLedger/fileList.vue b/src/views/procurementManagement/procurementLedger/fileList.vue
new file mode 100644
index 0000000..fb392c5
--- /dev/null
+++ b/src/views/procurementManagement/procurementLedger/fileList.vue
@@ -0,0 +1,67 @@
+<template>
+ <el-dialog v-model="dialogVisible" title="闄勪欢" width="40%" :before-close="handleClose">
+ <el-table :data="tableData" border height="40vh">
+ <el-table-column label="闄勪欢鍚嶇О" prop="name" min-width="400" show-overflow-tooltip />
+ <el-table-column fixed="right" label="鎿嶄綔" width="150" align="center">
+ <template #default="scope">
+ <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">涓嬭浇</el-button>
+ <el-button link type="primary" size="small" @click="lookFile(scope.row)">棰勮</el-button>
+ <el-button link type="danger" size="small" @click="handleDelete(scope.row)">鍒犻櫎</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-dialog>
+ <filePreview ref="filePreviewRef" />
+</template>
+
+<script setup>
+import { ref } from 'vue'
+import { ElMessageBox, ElMessage } from 'element-plus'
+import filePreview from '@/components/filePreview/index.vue'
+import { delCommonFile } from '@/api/publicApi/commonFile.js'
+
+const dialogVisible = ref(false)
+const tableData = ref([])
+const { proxy } = getCurrentInstance();
+const filePreviewRef = ref()
+const handleClose = () => {
+ dialogVisible.value = false
+}
+const open = (list) => {
+ dialogVisible.value = true
+ tableData.value = list
+}
+const downLoadFile = (row) => {
+ proxy.$download.name(row.url);
+
+}
+const lookFile = (row) => {
+ filePreviewRef.value.open(row.url)
+}
+// 鍒犻櫎闄勪欢
+const handleDelete = (row) => {
+ ElMessageBox.confirm(`纭鍒犻櫎闄勪欢"${row.name}"鍚楋紵`, '鍒犻櫎纭', {
+ confirmButtonText: '纭',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning',
+ }).then(() => {
+ delCommonFile([row.id]).then(() => {
+ ElMessage.success('鍒犻櫎鎴愬姛')
+ // 浠庡垪琛ㄤ腑绉婚櫎宸插垹闄ょ殑闄勪欢
+ const index = tableData.value.findIndex(item => item.id === row.id)
+ if (index !== -1) {
+ tableData.value.splice(index, 1)
+ }
+ }).catch(() => {
+ ElMessage.error('鍒犻櫎澶辫触')
+ })
+ }).catch(() => {
+ proxy.$modal.msg('宸插彇娑堝垹闄�')
+ })
+}
+defineExpose({
+ open
+})
+</script>
+
+<style></style>
\ No newline at end of file
diff --git a/src/views/procurementManagement/procurementLedger/index.vue b/src/views/procurementManagement/procurementLedger/index.vue
index 4fde128..9b86624 100644
--- a/src/views/procurementManagement/procurementLedger/index.vue
+++ b/src/views/procurementManagement/procurementLedger/index.vue
@@ -2,461 +2,442 @@
<div class="app-container">
<div class="search_form">
<div>
- <el-form :model="searchForm" :inline="true">
+ <el-form :model="searchForm"
+ :inline="true">
<el-form-item label="渚涘簲鍟嗗悕绉帮細">
- <el-input v-model="searchForm.supplierName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
+ <el-input v-model="searchForm.supplierName"
+ placeholder="璇疯緭鍏�"
+ clearable
+ prefix-icon="Search"
@change="handleQuery" />
</el-form-item>
<el-form-item label="閲囪喘鍚堝悓鍙凤細">
- <el-input
- v-model="searchForm.purchaseContractNumber"
- style="width: 240px"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
+ <el-input v-model="searchForm.purchaseContractNumber"
+ style="width: 240px"
+ placeholder="璇疯緭鍏�"
+ @change="handleQuery"
+ clearable
+ :prefix-icon="Search" />
</el-form-item>
<el-form-item label="閿�鍞悎鍚屽彿锛�">
- <el-input v-model="searchForm.salesContractNo" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
+ <el-input v-model="searchForm.salesContractNo"
+ placeholder="璇疯緭鍏�"
+ clearable
+ prefix-icon="Search"
@change="handleQuery" />
</el-form-item>
<el-form-item label="椤圭洰鍚嶇О锛�">
- <el-input v-model="searchForm.projectName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
+ <el-input v-model="searchForm.projectName"
+ placeholder="璇疯緭鍏�"
+ clearable
+ prefix-icon="Search"
@change="handleQuery" />
</el-form-item>
<el-form-item label="褰曞叆鏃ユ湡锛�">
- <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
- placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
+ <el-date-picker v-model="searchForm.entryDate"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ type="daterange"
+ placeholder="璇烽�夋嫨"
+ clearable
+ @change="changeDaterange" />
</el-form-item>
<el-form-item>
- <el-button type="primary" @click="handleQuery"> 鎼滅储 </el-button>
+ <el-button type="primary"
+ @click="handleQuery"> 鎼滅储 </el-button>
</el-form-item>
</el-form>
</div>
-
</div>
<div class="table_list">
<div style="display: flex;justify-content: flex-end;margin-bottom: 20px;">
- <el-button type="primary" @click="openForm('add')">鏂板鍙拌处</el-button>
+ <el-button type="primary"
+ @click="openForm('add')">鏂板鍙拌处</el-button>
+ <el-button type="success"
+ @click="openScanAddDialog">鎵爜鏂板</el-button>
<el-button @click="handleOut">瀵煎嚭</el-button>
- <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+ <el-button type="danger"
+ plain
+ @click="handleDelete">鍒犻櫎</el-button>
</div>
- <el-table
- :data="tableData"
- border
- v-loading="tableLoading"
- @selection-change="handleSelectionChange"
- :expand-row-keys="expandedRowKeys"
- :row-key="(row) => row.id"
- show-summary
- :summary-method="summarizeMainTable"
- @expand-change="expandChange"
- height="calc(100vh - 22em)"
- :row-class-name="tableRowClassName"
- >
- <el-table-column align="center" type="selection" width="55" />
+ <el-table :data="tableData"
+ border
+ v-loading="tableLoading"
+ @selection-change="handleSelectionChange"
+ :expand-row-keys="expandedRowKeys"
+ :row-key="(row) => row.id"
+ show-summary
+ :summary-method="summarizeMainTable"
+ @expand-change="expandChange"
+ height="calc(100vh - 19em)"
+ :row-class-name="tableRowClassName">
+ <el-table-column align="center"
+ type="selection"
+ width="55" />
<el-table-column type="expand">
<template #default="props">
- <el-table
- :data="props.row.children"
- border
- show-summary
- :summary-method="summarizeChildrenTable"
- >
- <el-table-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- />
- <el-table-column label="浜у搧澶х被" prop="productCategory" />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
- <el-table-column label="鍗曚綅" prop="unit" />
- <el-table-column label="鏁伴噺" prop="quantity" />
- <el-table-column label="绋庣巼(%)" prop="taxRate" />
- <el-table-column
- label="鍚◣鍗曚环(鍏�)"
- prop="taxInclusiveUnitPrice"
- :formatter="formattedNumber"
- />
- <el-table-column
- label="鍚◣鎬讳环(鍏�)"
- prop="taxInclusiveTotalPrice"
- :formatter="formattedNumber"
- />
- <el-table-column
- label="涓嶅惈绋庢�讳环(鍏�)"
- prop="taxExclusiveTotalPrice"
- :formatter="formattedNumber"
- />
+ <el-table :data="props.row.children"
+ border
+ show-summary
+ :summary-method="summarizeChildrenTable">
+ <el-table-column align="center"
+ label="搴忓彿"
+ type="index"
+ width="60" />
+ <el-table-column label="浜у搧澶х被"
+ prop="productCategory" />
+ <el-table-column label="瑙勬牸鍨嬪彿"
+ prop="specificationModel" />
+ <el-table-column label="鍗曚綅"
+ prop="unit" />
+ <el-table-column label="鏁伴噺"
+ prop="quantity" />
+ <el-table-column label="绋庣巼(%)"
+ prop="taxRate" />
+ <el-table-column label="鍚◣鍗曚环(鍏�)"
+ prop="taxInclusiveUnitPrice"
+ :formatter="formattedNumber" />
+ <el-table-column label="鍚◣鎬讳环(鍏�)"
+ prop="taxInclusiveTotalPrice"
+ :formatter="formattedNumber" />
+ <el-table-column label="涓嶅惈绋庢�讳环(鍏�)"
+ prop="taxExclusiveTotalPrice"
+ :formatter="formattedNumber" />
</el-table>
</template>
</el-table-column>
- <el-table-column align="center" label="搴忓彿" type="index" width="60" />
- <el-table-column
- label="閲囪喘鍚堝悓鍙�"
- prop="purchaseContractNumber"
- width="200"
- show-overflow-tooltip
- />
- <el-table-column
- label="閿�鍞悎鍚屽彿"
- prop="salesContractNo"
- width="200"
- show-overflow-tooltip
- />
- <el-table-column
- label="渚涘簲鍟嗗悕绉�"
- width="240"
- prop="supplierName"
- show-overflow-tooltip
- />
- <el-table-column label="璁㈠崟鐘舵��" width="100" align="center">
+ <el-table-column align="center"
+ label="搴忓彿"
+ type="index"
+ width="60" />
+ <el-table-column label="閲囪喘鍚堝悓鍙�"
+ prop="purchaseContractNumber"
+ width="200"
+ show-overflow-tooltip />
+ <el-table-column label="閿�鍞悎鍚屽彿"
+ prop="salesContractNo"
+ show-overflow-tooltip />
+ <el-table-column label="渚涘簲鍟嗗悕绉�"
+ prop="supplierName"
+ show-overflow-tooltip />
+ <el-table-column label="璁㈠崟鐘舵��"
+ width="100"
+ align="center">
<template #default="scope">
- <el-tag v-if="scope.row.isInvalid" type="danger" size="small">澶辨晥</el-tag>
- <el-tag v-else type="success" size="small">姝e父</el-tag>
+ <el-tag v-if="scope.row.isInvalid"
+ type="danger"
+ size="small">澶辨晥</el-tag>
+ <el-tag v-else
+ type="success"
+ size="small">姝e父</el-tag>
</template>
</el-table-column>
- <el-table-column
- label="椤圭洰鍚嶇О"
- prop="projectName"
- width="420"
- show-overflow-tooltip
- />
- <el-table-column
- label="瀹℃壒鐘舵��"
- prop="approvalStatus"
- width="200"
- show-overflow-tooltip
- >
+ <el-table-column label="椤圭洰鍚嶇О"
+ prop="projectName"
+ width="420"
+ show-overflow-tooltip />
+ <el-table-column label="瀹℃壒鐘舵��"
+ prop="approvalStatus"
+ width="200"
+ show-overflow-tooltip>
<template #default="scope">
- <el-tag
- size="small"
- >
+ <el-tag size="small">
{{ approvalStatusText[scope.row.approvalStatus] || '鏈煡鐘舵��' }}
</el-tag>
</template>
</el-table-column>
- <el-table-column
- label="浠樻鏂瑰紡"
- width="100"
- prop="paymentMethod"
- show-overflow-tooltip
- />
- <el-table-column
- label="鍚堝悓閲戦(鍏�)"
- prop="contractAmount"
- width="200"
- show-overflow-tooltip
- :formatter="formattedNumber"
- />
- <el-table-column
- label="褰曞叆浜�"
- prop="recorderName"
- width="100"
- show-overflow-tooltip
- />
- <el-table-column
- label="褰曞叆鏃ユ湡"
- prop="entryDate"
- width="100"
- show-overflow-tooltip
- />
- <el-table-column
- fixed="right"
- label="鎿嶄綔"
- width="100"
- align="center"
- >
+ <el-table-column label="绛捐鏃ユ湡"
+ prop="executionDate"
+ width="100"
+ show-overflow-tooltip />
+ <el-table-column label="浠樻鏂瑰紡"
+ width="100"
+ prop="paymentMethod"
+ show-overflow-tooltip />
+ <el-table-column label="鍚堝悓閲戦(鍏�)"
+ prop="contractAmount"
+ width="200"
+ show-overflow-tooltip
+ :formatter="formattedNumber" />
+ <el-table-column label="褰曞叆浜�"
+ prop="recorderName"
+ width="120"
+ show-overflow-tooltip />
+ <el-table-column label="褰曞叆鏃ユ湡"
+ prop="entryDate"
+ width="100"
+ show-overflow-tooltip />
+ <el-table-column fixed="right"
+ label="鎿嶄綔"
+ width="180"
+ align="center">
<template #default="scope">
- <el-button
- link
- type="primary"
- size="small"
- @click="openForm('edit', scope.row)"
- >缂栬緫</el-button
- >
-
+ <el-button link
+ type="primary"
+ size="small"
+ @click="openForm('edit', scope.row)">缂栬緫</el-button>
+ <el-button link
+ type="success"
+ size="small"
+ @click="showQRCode(scope.row)">鐢熸垚浜岀淮鐮�</el-button>
+ <el-button link
+ type="primary"
+ size="small"
+ @click="downLoadFile(scope.row)">闄勪欢</el-button>
</template>
</el-table-column>
</el-table>
- <pagination
- v-show="total > 0"
- :total="total"
- layout="total, sizes, prev, pager, next, jumper"
- :page="page.current"
- :limit="page.size"
- @pagination="paginationChange"
- />
+ <pagination v-show="total > 0"
+ :total="total"
+ layout="total, sizes, prev, pager, next, jumper"
+ :page="page.current"
+ :limit="page.size"
+ @pagination="paginationChange" />
</div>
- <FormDialog
- v-model="dialogFormVisible"
- :title="operationType === 'add' ? '鏂板閲囪喘鍙拌处椤甸潰' : '缂栬緫閲囪喘鍙拌处椤甸潰'"
- :width="'70%'"
- :operation-type="operationType"
- @close="closeDia"
- @confirm="submitForm"
- @cancel="closeDia"
- >
- <el-form
- :model="form"
- label-width="140px"
- label-position="top"
- :rules="rules"
- ref="formRef"
- >
+ <el-dialog v-model="dialogFormVisible"
+ :title="operationType === 'add' ? '鏂板閲囪喘鍙拌处椤甸潰' : '缂栬緫閲囪喘鍙拌处椤甸潰'"
+ width="70%"
+ @close="closeDia">
+ <el-form :model="form"
+ label-width="140px"
+ label-position="top"
+ :rules="rules"
+ ref="formRef">
<el-row :gutter="30">
<el-col :span="12">
- <el-form-item label="閲囪喘鍚堝悓鍙凤細" prop="purchaseContractNumber">
- <el-input
- v-model="form.purchaseContractNumber"
- placeholder="璇疯緭鍏�"
- clearable
- />
+ <el-form-item label="閲囪喘鍚堝悓鍙凤細"
+ prop="purchaseContractNumber">
+ <el-input v-model="form.purchaseContractNumber"
+ placeholder="璇疯緭鍏�"
+ clearable />
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesLedgerId">
- <el-select
- v-model="form.salesLedgerId"
- placeholder="璇烽�夋嫨"
- clearable
- @change="salesLedgerChange"
- >
- <el-option
- v-for="item in salesContractList"
- :key="item.id"
- :label="item.salesContractNo"
- :value="item.id"
- />
+ <el-form-item label="閿�鍞悎鍚屽彿锛�"
+ prop="salesLedgerId">
+ <el-select v-model="form.salesLedgerId"
+ placeholder="璇烽�夋嫨"
+ filterable
+ clearable
+ @change="salesLedgerChange">
+ <el-option v-for="item in salesContractList"
+ :key="item.id"
+ :label="item.salesContractNo"
+ :value="item.id" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
- <el-form-item label="渚涘簲鍟嗗悕绉帮細" prop="supplierId">
- <el-select
- v-model="form.supplierId"
- placeholder="璇烽�夋嫨"
- clearable
- filterable
- allow-create
- >
- <el-option
- v-for="item in supplierList"
- :key="item.id"
- :label="item.supplierName"
- :value="item.id"
- />
+ <el-form-item label="渚涘簲鍟嗗悕绉帮細"
+ prop="supplierId">
+ <el-select v-model="form.supplierId"
+ placeholder="璇烽�夋嫨"
+ filterable
+ clearable>
+ <el-option v-for="item in supplierList"
+ :key="item.id"
+ :label="item.supplierName"
+ :value="item.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectName">
- <el-input
- v-model="form.projectName"
- placeholder="璇疯緭鍏�"
- clearable
- />
+ <el-form-item label="椤圭洰鍚嶇О"
+ prop="projectName">
+ <el-input v-model="form.projectName"
+ placeholder="璇疯緭鍏�"
+ clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
<el-form-item label="浠樻鏂瑰紡">
- <el-input
- v-model="form.paymentMethod"
- placeholder="璇疯緭鍏�"
- clearable
- />
+ <el-input v-model="form.paymentMethod"
+ placeholder="璇疯緭鍏�"
+ clearable />
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="绛捐鏃ユ湡锛�" prop="executionDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.executionDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨"
- clearable
- />
+ <el-form-item label="绛捐鏃ユ湡锛�"
+ prop="executionDate">
+ <el-date-picker style="width: 100%"
+ v-model="form.executionDate"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ type="date"
+ placeholder="璇烽�夋嫨"
+ clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
- <el-form-item label="瀹℃壒浜猴細" prop="approverId">
- <el-select
- v-model="form.approverId"
- placeholder="璇烽�夋嫨瀹℃壒浜�"
- clearable
- >
- <el-option
- v-for="item in userList"
- :key="item.userId"
- :label="item.nickName"
- :value="item.userId"
- />
+ <el-form-item label="瀹℃壒浜猴細"
+ prop="approverId">
+ <el-select v-model="form.approverId"
+ placeholder="璇烽�夋嫨瀹℃壒浜�"
+ clearable>
+ <el-option v-for="item in userList"
+ :key="item.userId"
+ :label="item.nickName"
+ :value="item.userId" />
</el-select>
</el-form-item>
- <el-form-item label="褰曞叆浜猴細" prop="recorderId" v-show="false">
- <el-select
- v-model="form.recorderId"
- placeholder="璇烽�夋嫨"
- clearable
- disabled
- >
- <el-option
- v-for="item in userList"
- :key="item.userId"
- :label="item.nickName"
- :value="item.userId"
- />
+ <el-form-item label="褰曞叆浜猴細"
+ prop="recorderId"
+ v-show="false">
+ <el-select v-model="form.recorderId"
+ placeholder="璇烽�夋嫨"
+ clearable
+ disabled>
+ <el-option v-for="item in userList"
+ :key="item.userId"
+ :label="item.nickName"
+ :value="item.userId" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="褰曞叆鏃ユ湡锛�" prop="entryDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.entryDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨"
- clearable
- />
+ <el-form-item label="褰曞叆鏃ユ湡锛�"
+ prop="entryDate">
+ <el-date-picker style="width: 100%"
+ v-model="form.entryDate"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ type="date"
+ placeholder="璇烽�夋嫨"
+ clearable />
</el-form-item>
</el-col>
</el-row>
<el-row>
- <el-form-item label="浜у搧淇℃伅锛�" prop="entryDate">
- <el-button type="primary" @click="openProductForm('add')"
- >娣诲姞</el-button
- >
- <el-button plain type="danger" @click="deleteProduct"
- >鍒犻櫎</el-button
- >
+ <el-form-item label="浜у搧淇℃伅锛�"
+ prop="entryDate">
+ <el-button type="primary"
+ @click="openProductForm('add')">娣诲姞</el-button>
+ <el-button plain
+ type="danger"
+ @click="deleteProduct">鍒犻櫎</el-button>
</el-form-item>
- <div class="select-button-group" style="width: 220px; margin: 20px 0;" v-if="operationType === 'add'">
- <el-select
- filterable
- allow-create
- :reserve-keyword="true"
- :default-first-option="false"
- v-model="templateName"
- :input-value="filterInputValue"
- @filter-change="onTemplateFilterChange"
- @change="onTemplateChange"
- style="width: 180px; border-right: none; border-radius: 4px 0 0 4px;"
- placeholder="璇烽�夋嫨"
- class="no-arrow-select"
- >
- <el-option
- v-for="item in templateList"
- :key="item.value"
- :label="item.templateName"
- :value="item.templateName"
- ></el-option>
+ <div class="select-button-group"
+ style="width: 220px; margin: 20px 0;"
+ v-if="operationType === 'add'">
+ <el-select filterable
+ allow-create
+ :reserve-keyword="true"
+ :default-first-option="false"
+ v-model="templateName"
+ :input-value="filterInputValue"
+ @filter-change="onTemplateFilterChange"
+ @change="onTemplateChange"
+ style="width: 180px; border-right: none; border-radius: 4px 0 0 4px;"
+ placeholder="璇烽�夋嫨"
+ class="no-arrow-select">
+ <el-option v-for="item in templateList"
+ :key="item.value"
+ :label="item.templateName"
+ :value="item.templateName"></el-option>
</el-select>
<!-- 鎸夐挳锛氫笌 Select 楂樺害鍖归厤锛屽幓鎺夊乏渚ц竟妗嗭紝鏃犵紳琛旀帴 -->
- <el-button
- size="small"
- style="height: 32px; border-radius: 0 4px 4px 0; margin-left: -1px;"
- @click="handleButtonClick"
- :disabled="!templateName || templateName.trim() === '' || isTemplateNameDuplicate"
- >
+ <el-button size="small"
+ style="height: 32px; border-radius: 0 4px 4px 0; margin-left: -1px;"
+ @click="handleButtonClick"
+ :disabled="!templateName || templateName.trim() === '' || isTemplateNameDuplicate">
淇濆瓨
</el-button>
</div>
</el-row>
- <el-table
- :data="productData"
- border
- @selection-change="productSelected"
- show-summary
- :summary-method="summarizeProTable"
- >
- <el-table-column align="center" type="selection" width="55" />
- <el-table-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- />
- <el-table-column label="浜у搧澶х被" prop="productCategory" />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
- <el-table-column label="鍗曚綅" prop="unit" width="70" />
- <el-table-column label="鏁伴噺" prop="quantity" width="70" />
- <el-table-column label="搴撳瓨棰勮鏁伴噺" prop="warnNum" width="120" show-overflow-tooltip />
- <el-table-column label="绋庣巼(%)" prop="taxRate" width="80" />
- <el-table-column
- label="鍚◣鍗曚环(鍏�)"
- prop="taxInclusiveUnitPrice"
- :formatter="formattedNumber"
- width="150"
- />
- <el-table-column
- label="鍚◣鎬讳环(鍏�)"
- prop="taxInclusiveTotalPrice"
- :formatter="formattedNumber"
- width="150"
- />
- <el-table-column
- label="涓嶅惈绋庢�讳环(鍏�)"
- prop="taxExclusiveTotalPrice"
- :formatter="formattedNumber"
- width="150"
- />
- <el-table-column
- fixed="right"
- label="鎿嶄綔"
- min-width="60"
- align="center"
- >
+ <el-table :data="productData"
+ border
+ @selection-change="productSelected"
+ show-summary
+ :summary-method="summarizeProTable">
+ <el-table-column align="center"
+ type="selection"
+ width="55" />
+ <el-table-column align="center"
+ label="搴忓彿"
+ type="index"
+ width="60" />
+ <el-table-column label="浜у搧澶х被"
+ prop="productCategory" />
+ <el-table-column label="瑙勬牸鍨嬪彿"
+ prop="specificationModel" />
+ <el-table-column label="鍗曚綅"
+ prop="unit"
+ width="70" />
+ <el-table-column label="鏁伴噺"
+ prop="quantity"
+ width="70" />
+ <el-table-column label="搴撳瓨棰勮鏁伴噺"
+ prop="warnNum"
+ width="120"
+ show-overflow-tooltip />
+ <el-table-column label="绋庣巼(%)"
+ prop="taxRate"
+ width="80" />
+ <el-table-column label="鍚◣鍗曚环(鍏�)"
+ prop="taxInclusiveUnitPrice"
+ :formatter="formattedNumber"
+ width="150" />
+ <el-table-column label="鍚◣鎬讳环(鍏�)"
+ prop="taxInclusiveTotalPrice"
+ :formatter="formattedNumber"
+ width="150" />
+ <el-table-column label="涓嶅惈绋庢�讳环(鍏�)"
+ prop="taxExclusiveTotalPrice"
+ :formatter="formattedNumber"
+ width="150" />
+ <el-table-column label="鏄惁璐ㄦ"
+ prop="isChecked"
+ width="150">
<template #default="scope">
- <el-button
- link
- type="primary"
- size="small"
- @click="openProductForm('edit', scope.row, scope.$index)"
- >缂栬緫</el-button
- >
+ <el-tag :type="scope.row.isChecked ? 'success' : 'info'">
+ {{ scope.row.isChecked ? '鏄�' : '鍚�' }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column fixed="right"
+ label="鎿嶄綔"
+ min-width="60"
+ align="center">
+ <template #default="scope">
+ <el-button link
+ type="primary"
+ size="small"
+ @click="openProductForm('edit', scope.row, scope.$index)">缂栬緫</el-button>
</template>
</el-table-column>
</el-table>
<el-row :gutter="30">
<el-col :span="24">
- <el-form-item label="澶囨敞路锛�" prop="remark">
- <el-input
- v-model="form.remark"
- placeholder="璇疯緭鍏�"
- clearable
- type="textarea"
- :rows="2"
- />
+ <el-form-item label="澶囨敞路锛�"
+ prop="remark">
+ <el-input v-model="form.remark"
+ placeholder="璇疯緭鍏�"
+ clearable
+ type="textarea"
+ :rows="2" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="24">
- <el-form-item label="闄勪欢鏉愭枡锛�" prop="remark">
- <el-upload
- v-model:file-list="fileList"
- :action="upload.url"
- multiple
- ref="fileUpload"
- auto-upload
- :headers="upload.headers"
- :before-upload="handleBeforeUpload"
- :on-error="handleUploadError"
- :on-success="handleUploadSuccess"
- :on-remove="handleRemove"
- >
+ <el-form-item label="闄勪欢鏉愭枡锛�"
+ prop="remark">
+ <el-upload v-model:file-list="fileList"
+ :action="upload.url"
+ multiple
+ ref="fileUpload"
+ auto-upload
+ :headers="upload.headers"
+ :before-upload="handleBeforeUpload"
+ :on-error="handleUploadError"
+ :on-success="handleUploadSuccess"
+ :on-remove="handleRemove">
<el-button type="primary">涓婁紶</el-button>
<template #tip>
<div class="el-upload__tip">
@@ -469,509 +450,764 @@
</el-col>
</el-row>
</el-form>
- </FormDialog>
- <FormDialog
- v-model="productFormVisible"
- :title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'"
- :width="'40%'"
- :operation-type="productOperationType"
- @close="closeProductDia"
- @confirm="submitProduct"
- @cancel="closeProductDia"
- >
- <el-form
- :model="productForm"
- label-width="140px"
- label-position="top"
- :rules="productRules"
- ref="productFormRef"
- >
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary"
+ @click="submitForm">纭</el-button>
+ <el-button @click="closeDia">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+ <el-dialog v-model="productFormVisible"
+ :title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'"
+ width="40%"
+ @close="closeProductDia">
+ <el-form :model="productForm"
+ label-width="140px"
+ label-position="top"
+ :rules="productRules"
+ ref="productFormRef">
<el-row :gutter="30">
<el-col :span="24">
- <el-form-item label="浜у搧澶х被锛�" prop="productId">
- <el-tree-select
- v-model="productForm.productId"
- placeholder="璇烽�夋嫨"
- clearable
- check-strictly
- @change="getModels"
- :data="productOptions"
- :render-after-expand="false"
- style="width: 100%"
- />
+ <el-form-item label="浜у搧澶х被锛�"
+ prop="productId">
+ <el-tree-select v-model="productForm.productId"
+ placeholder="璇烽�夋嫨"
+ clearable
+ check-strictly
+ @change="getModels"
+ :data="productOptions"
+ :render-after-expand="false"
+ style="width: 100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="24">
- <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="productModelId">
- <el-select
- v-model="productForm.productModelId"
- placeholder="璇烽�夋嫨"
- clearable
- @change="getProductModel"
- >
- <el-option
- v-for="item in modelOptions"
- :key="item.id"
- :label="item.model"
- :value="item.id"
- />
+ <el-form-item label="瑙勬牸鍨嬪彿锛�"
+ prop="productModelId">
+ <el-select v-model="productForm.productModelId"
+ placeholder="璇烽�夋嫨"
+ clearable
+ @change="getProductModel">
+ <el-option v-for="item in modelOptions"
+ :key="item.id"
+ :label="item.model"
+ :value="item.id" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
- <el-form-item label="鍗曚綅锛�" prop="unit">
- <el-input
- v-model="productForm.unit"
- placeholder="璇疯緭鍏�"
- clearable
- />
+ <el-form-item label="鍗曚綅锛�"
+ prop="unit">
+ <el-input v-model="productForm.unit"
+ placeholder="璇疯緭鍏�"
+ clearable />
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="绋庣巼(%)锛�" prop="taxRate">
- <el-select
- v-model="productForm.taxRate"
- placeholder="璇烽�夋嫨"
- clearable
- @change="mathNum"
- >
- <el-option label="1" value="1" />
- <el-option label="6" value="6" />
- <el-option label="13" value="13" />
+ <el-form-item label="绋庣巼(%)锛�"
+ prop="taxRate">
+ <el-select v-model="productForm.taxRate"
+ placeholder="璇烽�夋嫨"
+ clearable
+ @change="mathNum">
+ <el-option label="1"
+ value="1" />
+ <el-option label="6"
+ value="6" />
+ <el-option label="13"
+ value="13" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
- <el-form-item label="鍚◣鍗曚环(鍏�)锛�" prop="taxInclusiveUnitPrice">
- <el-input-number
- v-model="productForm.taxInclusiveUnitPrice"
- :precision="2"
- :step="0.1"
- clearable
- style="width: 100%"
- @change="mathNum"
- />
+ <el-form-item label="鍚◣鍗曚环(鍏�)锛�"
+ prop="taxInclusiveUnitPrice">
+ <el-input-number v-model="productForm.taxInclusiveUnitPrice"
+ :precision="2"
+ :step="0.1"
+ :min="0"
+ clearable
+ style="width: 100%"
+ @change="mathNum" />
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="鏁伴噺锛�" prop="quantity">
- <el-input-number
- :step="0.1"
- clearable
- :precision="2"
- style="width: 100%"
- v-model="productForm.quantity"
- placeholder="璇疯緭鍏�"
- @change="mathNum"
- />
+ <el-form-item label="鏁伴噺锛�"
+ prop="quantity">
+ <el-input-number :step="0.1"
+ clearable
+ :precision="2"
+ :min="0"
+ style="width: 100%"
+ v-model="productForm.quantity"
+ placeholder="璇疯緭鍏�"
+ @change="mathNum" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
- <el-form-item label="鍚◣鎬讳环(鍏�)锛�" prop="taxInclusiveTotalPrice">
- <el-input-number
- v-model="productForm.taxInclusiveTotalPrice"
- :precision="2"
- :step="0.1"
- clearable
- style="width: 100%"
- @change="reverseMathNum('taxInclusiveTotalPrice')"
- />
+ <el-form-item label="鍚◣鎬讳环(鍏�)锛�"
+ prop="taxInclusiveTotalPrice">
+ <el-input-number v-model="productForm.taxInclusiveTotalPrice"
+ :precision="2"
+ :step="0.1"
+ :min="0"
+ clearable
+ style="width: 100%"
+ @change="reverseMathNum('taxInclusiveTotalPrice')" />
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item
- label="涓嶅惈绋庢�讳环(鍏�)锛�"
- prop="taxExclusiveTotalPrice"
- >
- <el-input
- v-model="productForm.taxExclusiveTotalPrice"
- @change="reverseMathNum('taxExclusiveTotalPrice')"
- />
+ <el-form-item label="涓嶅惈绋庢�讳环(鍏�)锛�"
+ prop="taxExclusiveTotalPrice">
+ <el-input-number v-model="productForm.taxExclusiveTotalPrice"
+ :precision="2"
+ :step="0.1"
+ :min="0"
+ clearable
+ style="width: 100%"
+ @change="reverseMathNum('taxExclusiveTotalPrice')" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
- <el-form-item label="鍙戠エ绫诲瀷锛�" prop="invoiceType">
- <el-select
- v-model="productForm.invoiceType"
- placeholder="璇烽�夋嫨"
- clearable
- >
- <el-option label="澧炴櫘绁�" value="澧炴櫘绁�" />
- <el-option label="澧炰笓绁�" value="澧炰笓绁�" />
+ <el-form-item label="鍙戠エ绫诲瀷锛�"
+ prop="invoiceType">
+ <el-select v-model="productForm.invoiceType"
+ placeholder="璇烽�夋嫨"
+ clearable>
+ <el-option label="澧炴櫘绁�"
+ value="澧炴櫘绁�" />
+ <el-option label="澧炰笓绁�"
+ value="澧炰笓绁�" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="搴撳瓨棰勮鏁伴噺锛�" prop="warnNum">
- <el-input-number
- v-model="productForm.warnNum"
- :precision="2"
- :step="0.1"
- clearable
- style="width: 100%"
- />
+ <el-form-item label="搴撳瓨棰勮鏁伴噺锛�"
+ prop="warnNum">
+ <el-input-number v-model="productForm.warnNum"
+ :precision="2"
+ :step="0.1"
+ :min="0"
+ clearable
+ style="width: 100%" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="鏄惁璐ㄦ锛�"
+ prop="isChecked">
+ <el-radio-group v-model="productForm.isChecked">
+ <el-radio label="鏄�"
+ :value="true" />
+ <el-radio label="鍚�"
+ :value="false" />
+ </el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-form>
- </FormDialog>
-
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary"
+ @click="submitProduct">纭</el-button>
+ <el-button @click="closeProductDia">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+ <!-- 浜岀淮鐮佹樉绀哄璇濇 -->
+ <el-dialog v-model="qrCodeDialogVisible"
+ title="閲囪喘鍚堝悓鍙蜂簩缁寸爜"
+ width="400px"
+ center>
+ <div style="text-align: center;">
+ <img :src="qrCodeUrl"
+ alt="浜岀淮鐮�"
+ style="width:200px;height:200px;" />
+ <div style="margin: 20px;">
+ <el-button type="primary"
+ @click="downloadQRCode">涓嬭浇浜岀淮鐮佸浘鐗�</el-button>
+ </div>
+ </div>
+ </el-dialog>
+ <!-- 鎵爜鏂板瀵硅瘽妗� -->
+ <el-dialog v-model="scanAddDialogVisible"
+ title="鎵爜鏂板閲囪喘鍙拌处"
+ width="70%"
+ @close="closeScanAddDialog">
+ <el-form :model="scanAddForm"
+ label-width="140px"
+ label-position="top"
+ :rules="scanAddRules"
+ ref="scanAddFormRef">
+ <el-row :gutter="20">
+ <el-col :span="24">
+ <el-form-item label="鎵爜鍐呭锛�">
+ <el-input v-model="scanAddForm.scanContent"
+ type="textarea"
+ :rows="3"
+ placeholder="璇锋壂鎻忎簩缁寸爜鎴栨墜鍔ㄨ緭鍏ラ噰璐悎鍚屼俊鎭�"
+ @input="parseScanContent" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="閲囪喘鍚堝悓鍙凤細"
+ prop="purchaseContractNumber">
+ <el-input v-model="scanAddForm.purchaseContractNumber"
+ placeholder="璇疯緭鍏�"
+ clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="渚涘簲鍟嗗悕绉帮細"
+ prop="supplierName">
+ <el-input v-model="scanAddForm.supplierName"
+ placeholder="璇疯緭鍏�"
+ clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="椤圭洰鍚嶇О锛�"
+ prop="projectName">
+ <el-input v-model="scanAddForm.projectName"
+ placeholder="璇疯緭鍏�"
+ clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鍚堝悓閲戦(鍏�)锛�"
+ prop="contractAmount">
+ <el-input-number v-model="scanAddForm.contractAmount"
+ :precision="2"
+ :step="0.1"
+ clearable
+ style="width: 100%"
+ placeholder="璇疯緭鍏�" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="浠樻鏂瑰紡锛�">
+ <el-input v-model="scanAddForm.paymentMethod"
+ placeholder="璇疯緭鍏�"
+ clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="褰曞叆浜猴細">
+ <el-input v-model="scanAddForm.recorderName"
+ disabled />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="24">
+ <el-form-item label="澶囨敞锛�">
+ <el-input v-model="scanAddForm.remark"
+ type="textarea"
+ :rows="2"
+ placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
+ clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary"
+ @click="submitScanAdd">纭鏂板</el-button>
+ <el-button @click="closeScanAddDialog">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+ <!-- 鎵爜鐧昏瀵硅瘽妗� -->
+ <el-dialog v-model="scanDialogVisible"
+ title="鎵爜鐧昏"
+ width="60%"
+ @close="closeScanDialog">
+ <el-form :model="scanForm"
+ label-width="120px"
+ label-position="left"
+ :rules="scanRules"
+ ref="scanFormRef">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="閲囪喘鍚堝悓鍙凤細">
+ <el-input v-model="scanForm.purchaseContractNumber"
+ disabled />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="渚涘簲鍟嗗悕绉帮細">
+ <el-input v-model="scanForm.supplierName"
+ disabled />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="椤圭洰鍚嶇О锛�">
+ <el-input v-model="scanForm.projectName"
+ disabled />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鎵爜鏃堕棿锛�">
+ <el-input v-model="scanForm.scanTime"
+ disabled />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鎵爜浜猴細">
+ <el-input v-model="scanForm.scannerName"
+ disabled />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鎵爜鐘舵�侊細">
+ <el-tag :type="scanForm.scanStatus === '宸叉壂鐮�' ? 'success' : 'warning'">
+ {{ scanForm.scanStatus }}
+ </el-tag>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="24">
+ <el-form-item label="鎵爜澶囨敞锛�">
+ <el-input v-model="scanForm.scanRemark"
+ type="textarea"
+ :rows="3"
+ placeholder="璇疯緭鍏ユ壂鐮佸娉ㄤ俊鎭�" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="24">
+ <el-form-item label="鎵爜璁板綍锛�">
+ <el-table :data="scanRecords"
+ border
+ style="width: 100%">
+ <el-table-column label="搴忓彿"
+ type="index"
+ width="60"
+ align="center" />
+ <el-table-column label="鎵爜鏃堕棿"
+ prop="scanTime"
+ width="180" />
+ <el-table-column label="鎵爜浜�"
+ prop="scannerName"
+ width="120" />
+ <el-table-column label="鎵爜鐘舵��"
+ prop="scanStatus"
+ width="100">
+ <template #default="scope">
+ <el-tag :type="scope.row.scanStatus === '宸叉壂鐮�' ? 'success' : 'warning'">
+ {{ scope.row.scanStatus }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column label="澶囨敞"
+ prop="scanRemark" />
+ </el-table>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary"
+ @click="submitScan">纭鎵爜</el-button>
+ <el-button @click="closeScanDialog">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+ <FileList ref="fileListRef" />
</div>
</template>
<script setup>
-import {getToken} from "@/utils/auth";
-import pagination from "@/components/PIMTable/Pagination.vue";
-import FormDialog from '@/components/Dialog/FormDialog.vue';
-import {getCurrentInstance, nextTick, onMounted, reactive, ref, toRefs} from "vue";
-import {Search} from "@element-plus/icons-vue";
-import {ElMessage, ElMessageBox} from "element-plus";
-import {userListNoPage} from "@/api/system/user.js";
-import {
- addOrUpdateSalesLedgerProduct,
- delLedgerFile,
- delProduct,
- getProductInfoByContractNo,
- getSalesLedgerWithProducts,
-} from "@/api/salesManagement/salesLedger.js";
-import {
- addOrEditPurchase,
- addPurchaseTemplate,
- createPurchaseNo,
- delPurchase,
- getOptions,
- getPurchaseById,
- getPurchaseTemplateList,
- getSalesNo,
- productList,
- purchaseListPage
-} from "@/api/procurementManagement/procurementLedger.js";
-import useFormData from "@/hooks/useFormData.js";
-import useUserStore from "@/store/modules/user";
-import {modelList, productTreeList} from "@/api/basicData/product.js";
-import dayjs from "dayjs";
-import { getCurrentDate } from "@/utils/index.js";
+ import { getToken } from "@/utils/auth";
+ import pagination from "@/components/PIMTable/Pagination.vue";
+ import {
+ ref,
+ onMounted,
+ reactive,
+ toRefs,
+ getCurrentInstance,
+ nextTick,
+ } from "vue";
+ import { Search } from "@element-plus/icons-vue";
+ import { ElMessageBox, ElMessage } from "element-plus";
+ import { userListNoPage } from "@/api/system/user.js";
+ import FileList from "./fileList.vue";
+ import {
+ getSalesLedgerWithProducts,
+ addOrUpdateSalesLedgerProduct,
+ delProduct,
+ delLedgerFile,
+ getProductInfoByContractNo,
+ } from "@/api/salesManagement/salesLedger.js";
+ import {
+ addOrEditPurchase,
+ addPurchaseTemplate,
+ createPurchaseNo,
+ delPurchase,
+ getSalesNo,
+ purchaseListPage,
+ productList,
+ getPurchaseById,
+ getOptions,
+ getPurchaseTemplateList,
+ } from "@/api/procurementManagement/procurementLedger.js";
+ import useFormData from "@/hooks/useFormData.js";
+ import QRCode from "qrcode";
-const { proxy } = getCurrentInstance();
-const tableData = ref([]);
-const productData = ref([]);
-const selectedRows = ref([]);
-const productSelectedRows = ref([]);
-const modelOptions = ref([]);
-const userList = ref([]);
-const productOptions = ref([]);
-const salesContractList = ref([]);
-const supplierList = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
-});
-const total = ref(0);
-const fileList = ref([]);
+ const { proxy } = getCurrentInstance();
+ const tableData = ref([]);
+ const productData = ref([]);
+ const selectedRows = ref([]);
+ const productSelectedRows = ref([]);
+ const modelOptions = ref([]);
+ const userList = ref([]);
+ const productOptions = ref([]);
+ const salesContractList = ref([]);
+ const supplierList = ref([]);
+ const tableLoading = ref(false);
+ const page = reactive({
+ current: 1,
+ size: 100,
+ });
+ const total = ref(0);
+ const fileList = ref([]);
+ import useUserStore from "@/store/modules/user";
+ import { modelList, productTreeList } from "@/api/basicData/product.js";
+ import dayjs from "dayjs";
-const userStore = useUserStore();
+ const userStore = useUserStore();
-// 璁㈠崟瀹℃壒鐘舵�佹樉绀烘枃鏈�
-const approvalStatusText = {
- 0: '瀹℃壒涓�',
- 1: '瀹℃壒閫氳繃',
- 2: '瀹℃壒澶辫触'
-};
+ // 浜岀淮鐮佺浉鍏冲彉閲�
+ const qrCodeDialogVisible = ref(false);
+ const qrCodeUrl = ref("");
+ // 璁㈠崟瀹℃壒鐘舵�佹樉绀烘枃鏈�
+ const approvalStatusText = {
+ 0: "瀹℃壒涓�",
+ 1: "瀹℃壒閫氳繃",
+ 2: "瀹℃壒澶辫触",
+ };
-const templateName = ref('');
-const filterInputValue = ref('');
-const templateList = ref([]);
-const isTemplateNameDuplicate = ref(false); // 鏍囪妯℃澘鍚嶇О鏄惁閲嶅
-
-// 妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶�
-const checkTemplateNameDuplicate = (name) => {
- if (!name || name.trim() === '') {
- isTemplateNameDuplicate.value = false;
- return false;
- }
- const isDuplicate = templateList.value.some(item => item.templateName === name.trim());
- isTemplateNameDuplicate.value = isDuplicate;
- return isDuplicate;
-};
-
-// 闃叉姈瀹氭椂鍣�
-let duplicateCheckTimer = null;
-const onTemplateFilterChange = (val) => {
- filterInputValue.value = val ?? '';
- // 娓呴櫎涔嬪墠鐨勫畾鏃跺櫒
- if (duplicateCheckTimer) {
- clearTimeout(duplicateCheckTimer);
- }
- // 瀹炴椂妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶嶏紙闃叉姈澶勭悊锛岄伩鍏嶉绻佹彁绀猴級
- if (val && val.trim()) {
- duplicateCheckTimer = setTimeout(() => {
- const isDuplicate = checkTemplateNameDuplicate(val);
- if (isDuplicate) {
- ElMessage({
- message: '妯℃澘鍚嶇О宸插瓨鍦紝璇锋洿鎹㈡ā鏉垮悕绉�',
- type: 'warning',
- duration: 2000
- });
- }
- }, 300); // 300ms 闃叉姈
- } else {
- isTemplateNameDuplicate.value = false;
- }
-};
-
-// allow-create 鏃讹紝杈撳叆涓嶅瓨鍦ㄧ殑鍐呭浼氫綔涓� string 鍊艰繑鍥烇紱杩欓噷鍚屾鍥炶緭鍏ユ浠ョ‘淇濇枃瀛椾笉涓�
-const onTemplateChange = async (val) => {
- if (typeof val === 'string') {
- filterInputValue.value = val;
- // 閫夋嫨鎴栬緭鍏ユ椂妫�鏌ラ噸澶�
- checkTemplateNameDuplicate(val);
- }
-
- // 杩囨护鏁版嵁锛屾煡鎵惧尮閰嶇殑妯℃澘
- const matchedTemplate = templateList.value.find(item => item.templateName === val);
-
- if (matchedTemplate?.id) {
- // 濡傛灉鎵惧埌妯℃澘锛屽姞杞芥ā鏉挎暟鎹�
- form.value = {
- ...form.value,
- ...matchedTemplate,
- };
- productData.value = matchedTemplate.productData || [];
- // 鐢熸垚鏂扮殑閲囪喘鍚堝悓鍙�
- try {
- const res = await createPurchaseNo();
- if (res?.data) {
- form.value.purchaseContractNumber = res.data;
- }
- } catch (error) {
- console.error('鐢熸垚閲囪喘鍚堝悓鍙峰け璐�:', error);
- }
- } else {
- // 濡傛灉娌℃湁鎵惧埌妯℃澘锛岄噸缃〃鍗曪紙淇濇寔褰撳墠琛ㄥ崟鐘舵�侊級
- const currentFormData = { ...form.value };
- const currentProductData = [...productData.value];
-
- // 濡傛灉瀵硅瘽妗嗘湭鎵撳紑锛屽厛鎵撳紑
- if (!dialogFormVisible.value) {
- operationType.value = 'add';
- dialogFormVisible.value = true;
- }
-
- // 绛夊緟涓嬩竴涓� tick 鍚庢仮澶嶆暟鎹�
- await nextTick();
- form.value = {
- ...form.value,
- ...currentFormData,
- };
- productData.value = currentProductData;
- }
-};
-
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref("");
-const dialogFormVisible = ref(false);
-const data = reactive({
- searchForm: {
- supplierName: "", // 渚涘簲鍟嗗悕绉�
- purchaseContractNumber: "", // 閲囪喘鍚堝悓缂栧彿
- salesContractNo: "", // 閿�鍞悎鍚岀紪鍙�
- projectName: "", // 椤圭洰鍚嶇О
- entryDate: null, // 褰曞叆鏃ユ湡
- entryDateStart: undefined,
- entryDateEnd: undefined,
- },
- form: {
- purchaseContractNumber: "",
- salesLedgerId: "",
- projectName: "",
- recorderId: "",
- entryDate: "",
- productData: [],
- supplierName: "",
- supplierId: "",
- paymentMethod: "",
- executionDate: "",
- },
- rules: {
- purchaseContractNumber: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- projectName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- supplierId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- entryDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- approverId:[{ required: true, message: "璇烽�夋嫨瀹℃壒浜�", trigger: "change" }],
- executionDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- },
-});
-const { form, rules } = toRefs(data);
-const { form: searchForm } = useFormData(data.searchForm);
-
-// 浜у搧琛ㄥ崟寮规鏁版嵁
-const productFormVisible = ref(false);
-const productOperationType = ref("");
-const productOperationIndex = ref("");
-const currentId = ref("");
-const productFormData = reactive({
- productForm: {
- productId: "",
- productCategory: "",
- productModelId: "",
- specificationModel: "",
- unit: "",
- quantity: "",
- taxInclusiveUnitPrice: "",
- taxRate: "",
- taxInclusiveTotalPrice: "",
- taxExclusiveTotalPrice: "",
- invoiceType: "",
- warnNum: "",
- },
- productRules: {
- productId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- productModelId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- taxInclusiveUnitPrice: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- taxRate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- warnNum: [{ required: false, message: "璇烽�夋嫨", trigger: "change" }],
- taxInclusiveTotalPrice: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- taxExclusiveTotalPrice: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- invoiceType: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- },
-});
-const { productForm, productRules } = toRefs(productFormData);
-const upload = reactive({
- // 涓婁紶鐨勫湴鍧�
- url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
- // 璁剧疆涓婁紶鐨勮姹傚ご閮�
- headers: { Authorization: "Bearer " + getToken() },
-});
-
-const changeDaterange = (value) => {
- if (value) {
- searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
- searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
- } else {
- searchForm.entryDateStart = undefined;
- searchForm.entryDateEnd = undefined;
- }
- handleQuery();
-};
-
-const formattedNumber = (row, column, cellValue) => {
- if (cellValue === null || cellValue === undefined || cellValue === '') {
- return '0.00';
- }
- const num = parseFloat(cellValue);
- if (isNaN(num)) {
- return '0.00';
- }
- return num.toFixed(2);
-};
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-
-// 淇濆瓨妯℃澘
-const handleButtonClick = async () => {
- // 妫�鏌ユā鏉垮悕绉版槸鍚︿负绌�
- if (!templateName.value || templateName.value.trim() === '') {
- ElMessage({
- message: '璇疯緭鍏ユā鏉垮悕绉�',
- type: 'warning',
- });
- return;
- }
+ const templateName = ref("");
+ const filterInputValue = ref("");
+ const templateList = ref([]);
+ const isTemplateNameDuplicate = ref(false); // 鏍囪妯℃澘鍚嶇О鏄惁閲嶅
// 妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶�
- const isDuplicate = checkTemplateNameDuplicate(templateName.value);
- if (isDuplicate) {
- ElMessage({
- message: '妯℃澘鍚嶇О宸插瓨鍦紝璇锋洿鎹㈡ā鏉垮悕绉�',
- type: 'warning',
- });
- return;
- }
-
- // 妫�鏌ヤ緵搴斿晢鏄惁閫夋嫨
- if (!form.value.supplierId) {
- ElMessage({
- message: '璇峰厛閫夋嫨渚涘簲鍟�',
- type: 'warning',
- });
- return;
- }
-
- // 妫�鏌ユ槸鍚︽湁浜у搧鏁版嵁
- // if (!productData.value || productData.value.length === 0) {
- // ElMessage({
- // message: '璇峰厛娣诲姞浜у搧淇℃伅',
- // type: 'warning',
- // });
- // return;
- // }
-
- try {
- let params = {
- productData: proxy.HaveJson(productData.value),
- supplierId: form.value.supplierId,
- paymentMethod: form.value.paymentMethod,
- recorderId: form.value.recorderId,
- approverId: form.value.approverId,
- templateName: templateName.value.trim()
- };
- console.log(params);
- let res = await addPurchaseTemplate(params);
-
- if (res && res.code === 200) {
- ElMessage({
- message: '妯℃澘淇濆瓨鎴愬姛',
- type: 'success',
- });
- // 淇濆瓨鎴愬姛鍚庨噸鏂拌幏鍙栨ā鏉垮垪琛�
- await getTemplateList();
- // 娓呯┖妯℃澘鍚嶇О杈撳叆
- templateName.value = '';
- filterInputValue.value = '';
+ const checkTemplateNameDuplicate = name => {
+ if (!name || name.trim() === "") {
isTemplateNameDuplicate.value = false;
+ return false;
+ }
+ const isDuplicate = templateList.value.some(
+ item => item.templateName === name.trim()
+ );
+ isTemplateNameDuplicate.value = isDuplicate;
+ return isDuplicate;
+ };
+
+ // 闃叉姈瀹氭椂鍣�
+ let duplicateCheckTimer = null;
+ const onTemplateFilterChange = val => {
+ filterInputValue.value = val ?? "";
+ // 娓呴櫎涔嬪墠鐨勫畾鏃跺櫒
+ if (duplicateCheckTimer) {
+ clearTimeout(duplicateCheckTimer);
+ }
+ // 瀹炴椂妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶嶏紙闃叉姈澶勭悊锛岄伩鍏嶉绻佹彁绀猴級
+ if (val && val.trim()) {
+ duplicateCheckTimer = setTimeout(() => {
+ const isDuplicate = checkTemplateNameDuplicate(val);
+ if (isDuplicate) {
+ ElMessage({
+ message: "妯℃澘鍚嶇О宸插瓨鍦紝璇锋洿鎹㈡ā鏉垮悕绉�",
+ type: "warning",
+ duration: 2000,
+ });
+ }
+ }, 300); // 300ms 闃叉姈
} else {
+ isTemplateNameDuplicate.value = false;
+ }
+ };
+
+ // allow-create 鏃讹紝杈撳叆涓嶅瓨鍦ㄧ殑鍐呭浼氫綔涓� string 鍊艰繑鍥烇紱杩欓噷鍚屾鍥炶緭鍏ユ浠ョ‘淇濇枃瀛椾笉涓�
+ const onTemplateChange = async val => {
+ if (typeof val === "string") {
+ filterInputValue.value = val;
+ // 閫夋嫨鎴栬緭鍏ユ椂妫�鏌ラ噸澶�
+ checkTemplateNameDuplicate(val);
+ }
+
+ // 杩囨护鏁版嵁锛屾煡鎵惧尮閰嶇殑妯℃澘
+ const matchedTemplate = templateList.value.find(
+ item => item.templateName === val
+ );
+
+ if (matchedTemplate?.id) {
+ // 濡傛灉鎵惧埌妯℃澘锛屽姞杞芥ā鏉挎暟鎹�
+ form.value = {
+ ...form.value,
+ ...matchedTemplate,
+ };
+ productData.value = matchedTemplate.productData || [];
+ // 鐢熸垚鏂扮殑閲囪喘鍚堝悓鍙�
+ try {
+ const res = await createPurchaseNo();
+ if (res?.data) {
+ form.value.purchaseContractNumber = res.data;
+ }
+ } catch (error) {
+ console.error("鐢熸垚閲囪喘鍚堝悓鍙峰け璐�:", error);
+ }
+ } else {
+ // 濡傛灉娌℃湁鎵惧埌妯℃澘锛岄噸缃〃鍗曪紙淇濇寔褰撳墠琛ㄥ崟鐘舵�侊級
+ const currentFormData = { ...form.value };
+ const currentProductData = [...productData.value];
+
+ // 濡傛灉瀵硅瘽妗嗘湭鎵撳紑锛屽厛鎵撳紑
+ if (!dialogFormVisible.value) {
+ operationType.value = "add";
+ dialogFormVisible.value = true;
+ }
+
+ // 绛夊緟涓嬩竴涓� tick 鍚庢仮澶嶆暟鎹�
+ await nextTick();
+ form.value = {
+ ...form.value,
+ ...currentFormData,
+ };
+ productData.value = currentProductData;
+ }
+ };
+
+ // 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
+ const operationType = ref("");
+ const dialogFormVisible = ref(false);
+ const data = reactive({
+ searchForm: {
+ supplierName: "", // 渚涘簲鍟嗗悕绉�
+ purchaseContractNumber: "", // 閲囪喘鍚堝悓缂栧彿
+ salesContractNo: "", // 閿�鍞悎鍚岀紪鍙�
+ projectName: "", // 椤圭洰鍚嶇О
+ entryDate: null, // 褰曞叆鏃ユ湡
+ entryDateStart: undefined,
+ entryDateEnd: undefined,
+ },
+ form: {
+ purchaseContractNumber: "",
+ salesLedgerId: "",
+ projectName: "",
+ recorderId: "",
+ entryDate: "",
+ productData: [],
+ supplierName: "",
+ supplierId: "",
+ paymentMethod: "",
+ executionDate: "",
+ isChecked: true,
+ },
+ rules: {
+ purchaseContractNumber: [
+ { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+ ],
+ approverId: [
+ { required: true, message: "璇烽�夋嫨瀹℃壒浜�", trigger: "change" },
+ ],
+ projectName: [
+ { required: true, message: "璇疯緭鍏ラ」鐩悕绉�", trigger: "blur" },
+ ],
+ supplierId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ entryDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ executionDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ },
+ });
+ const { form, rules } = toRefs(data);
+ const { form: searchForm } = useFormData({
+ ...data.searchForm,
+ // 璁剧疆褰曞叆鏃ユ湡鑼冨洿涓哄綋澶�
+ entryDate: [
+ dayjs().startOf("day").format("YYYY-MM-DD"),
+ dayjs().endOf("day").format("YYYY-MM-DD"),
+ ],
+ entryDateStart: dayjs().startOf("day").format("YYYY-MM-DD"),
+ entryDateEnd: dayjs().endOf("day").format("YYYY-MM-DD"),
+ });
+
+ // 浜у搧琛ㄥ崟寮规鏁版嵁
+ const productFormVisible = ref(false);
+ const productOperationType = ref("");
+ const productOperationIndex = ref("");
+ const currentId = ref("");
+ const productFormData = reactive({
+ productForm: {
+ productId: "",
+ productCategory: "",
+ productModelId: "",
+ specificationModel: "",
+ unit: "",
+ quantity: "",
+ taxInclusiveUnitPrice: "",
+ taxRate: "",
+ taxInclusiveTotalPrice: "",
+ taxExclusiveTotalPrice: "",
+ invoiceType: "",
+ warnNum: "",
+ isChecked: true,
+ },
+ productRules: {
+ productId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ productModelId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ taxInclusiveUnitPrice: [
+ { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+ ],
+ taxRate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ warnNum: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ taxInclusiveTotalPrice: [
+ { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+ ],
+ taxExclusiveTotalPrice: [
+ { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+ ],
+ invoiceType: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ isChecked: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ },
+ });
+ const { productForm, productRules } = toRefs(productFormData);
+ const upload = reactive({
+ // 涓婁紶鐨勫湴鍧�
+ url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
+ // 璁剧疆涓婁紶鐨勮姹傚ご閮�
+ headers: { Authorization: "Bearer " + getToken() },
+ });
+
+ const changeDaterange = value => {
+ if (value) {
+ searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
+ searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
+ } else {
+ searchForm.entryDateStart = undefined;
+ searchForm.entryDateEnd = undefined;
+ }
+ handleQuery();
+ };
+
+ const formattedNumber = (row, column, cellValue) => {
+ return parseFloat(cellValue).toFixed(2);
+ };
+ // 鏌ヨ鍒楄〃
+ /** 鎼滅储鎸夐挳鎿嶄綔 */
+ const handleQuery = () => {
+ page.current = 1;
+ getList();
+ };
+
+ // 淇濆瓨妯℃澘
+ const handleButtonClick = async () => {
+ // 妫�鏌ユā鏉垮悕绉版槸鍚︿负绌�
+ if (!templateName.value || templateName.value.trim() === "") {
ElMessage({
- message: res?.msg || '妯℃澘淇濆瓨澶辫触',
- type: 'error',
+ message: "璇疯緭鍏ユā鏉垮悕绉�",
+ type: "warning",
+ });
+ return;
+ }
+
+ // 妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶�
+ const isDuplicate = checkTemplateNameDuplicate(templateName.value);
+ if (isDuplicate) {
+ ElMessage({
+ message: "妯℃澘鍚嶇О宸插瓨鍦紝璇锋洿鎹㈡ā鏉垮悕绉�",
+ type: "warning",
+ });
+ return;
+ }
+
+ // 妫�鏌ヤ緵搴斿晢鏄惁閫夋嫨
+ if (!form.value.supplierId) {
+ ElMessage({
+ message: "璇峰厛閫夋嫨渚涘簲鍟�",
+ type: "warning",
+ });
+ return;
+ }
+
+ // 妫�鏌ユ槸鍚︽湁浜у搧鏁版嵁
+ // if (!productData.value || productData.value.length === 0) {
+ // ElMessage({
+ // message: '璇峰厛娣诲姞浜у搧淇℃伅',
+ // type: 'warning',
+ // });
+ // return;
+ // }
+
+ try {
+ let params = {
+ productData: proxy.HaveJson(productData.value),
+ supplierId: form.value.supplierId,
+ paymentMethod: form.value.paymentMethod,
+ recorderId: form.value.recorderId,
+ approverId: form.value.approverId,
+ templateName: templateName.value.trim(),
+ };
+ console.log(params);
+ let res = await addPurchaseTemplate(params);
+
+ if (res && res.code === 200) {
+ ElMessage({
+ message: "妯℃澘淇濆瓨鎴愬姛",
+ type: "success",
+ });
+ // 淇濆瓨鎴愬姛鍚庨噸鏂拌幏鍙栨ā鏉垮垪琛�
+ await getTemplateList();
+ // 娓呯┖妯℃澘鍚嶇О杈撳叆
+ templateName.value = "";
+ filterInputValue.value = "";
+ isTemplateNameDuplicate.value = false;
+ } else {
+ ElMessage({
+ message: res?.msg || "妯℃澘淇濆瓨澶辫触",
+ type: "error",
+ });
+ }
+ } catch (error) {
+ console.error("淇濆瓨妯℃澘澶辫触:", error);
+ ElMessage({
+ message: "妯℃澘淇濆瓨澶辫触锛岃绋嶅悗閲嶈瘯",
+ type: "error",
});
}
- } catch (error) {
- console.error('淇濆瓨妯℃澘澶辫触:', error);
- ElMessage({
- message: '妯℃澘淇濆瓨澶辫触锛岃绋嶅悗閲嶈瘯',
- type: 'error',
- });
- }
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeChildrenTable = (param) => {
- return proxy.summarizeTable(
+ };
+ // 瀛愯〃鍚堣鏂规硶
+ const summarizeChildrenTable = param => {
+ return proxy.summarizeTable(
param,
[
"taxInclusiveUnitPrice",
@@ -986,27 +1222,26 @@
ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
}
- );
-};
-const paginationChange = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- const { entryDate, ...rest } = searchForm;
- purchaseListPage({ ...rest, ...page })
- .then((res) => {
+ );
+ };
+ const paginationChange = obj => {
+ page.current = obj.page;
+ page.size = obj.limit;
+ getList();
+ };
+ const getList = () => {
+ tableLoading.value = true;
+ const { entryDate, ...rest } = searchForm;
+ purchaseListPage({ ...rest, ...page })
+ .then(res => {
tableLoading.value = false;
// tableData.value = res.data.records;
- // 澶勭悊鏁版嵁锛屾坊鍔犲け鏁堢姸鎬佹爣璁�
tableData.value = res.data.records.map(record => ({
...record,
- isInvalid: record.isWhite === 1
+ isInvalid: record.isWhite === 1,
}));
// 鍒濆鍖栧瓙鏁版嵁鏁扮粍
- tableData.value.forEach((item) => {
+ tableData.value.forEach(item => {
item.children = [];
});
total.value = res.data.total;
@@ -1015,547 +1250,758 @@
.catch(() => {
tableLoading.value = false;
});
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-const productSelected = (selectedRows) => {
- productSelectedRows.value = selectedRows;
-};
-const expandedRowKeys = ref([]);
-// 灞曞紑琛�
-const expandChange = async (row, expandedRows) => {
- if (expandedRows.length > 0) {
- expandedRowKeys.value = [];
- try {
- const res = await productList({ salesLedgerId: row.id, type: 2 });
- const index = tableData.value.findIndex((item) => item.id === row.id);
- if (index > -1) {
- tableData.value[index].children = res.data || [];
- expandedRowKeys.value.push(row.id);
- }
- } catch (error) {
- console.error('鍔犺浇浜у搧鍒楄〃澶辫触:', error);
- proxy.$modal.msgError('鍔犺浇浜у搧鍒楄〃澶辫触');
- // 灞曞紑澶辫触鏃讹紝绉婚櫎灞曞紑鐘舵��
- const index = expandedRows.findIndex(item => item.id === row.id);
- if (index > -1) {
- expandedRows.splice(index, 1);
- }
- }
- } else {
- expandedRowKeys.value = [];
- }
-};
-// 涓昏〃鍚堣鏂规硶
-const summarizeMainTable = (param) => {
- return proxy.summarizeTable(param, ["contractAmount"]);
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeProTable = (param) => {
- return proxy.summarizeTable(param, [
- "taxInclusiveUnitPrice",
- "taxInclusiveTotalPrice",
- "taxExclusiveTotalPrice",
- ]);
-};
-// 鎵撳紑寮规
-const openForm = async (type, row) => {
- await getTemplateList()
- operationType.value = type;
- form.value = {};
- productData.value = [];
- fileList.value = [];
- templateName.value = '';
- filterInputValue.value = '';
- isTemplateNameDuplicate.value = false;
- try {
- // 骞惰鍔犺浇鍩虹鏁版嵁
- const [userRes, salesRes, supplierRes] = await Promise.all([
- userListNoPage(),
- getSalesNo(),
- getOptions()
- ]);
-
- userList.value = userRes.data || [];
- salesContractList.value = salesRes || [];
- // 渚涘簲鍟嗚繃婊ゅ嚭isWhite=0 鐨勬暟鎹�
- supplierList.value = (supplierRes.data || []).filter((item) => item.isWhite === 0);
-
- // 璁剧疆榛樿鍊�
- form.value.recorderId = userStore.id;
- form.value.entryDate = getCurrentDate();
-
- if (type === "add") {
- // 鏂板鏃剁敓鎴愰噰璐悎鍚屽彿
+ };
+ // 琛ㄦ牸閫夋嫨鏁版嵁
+ const handleSelectionChange = selection => {
+ selectedRows.value = selection;
+ };
+ const productSelected = selectedRows => {
+ productSelectedRows.value = selectedRows;
+ };
+ const expandedRowKeys = ref([]);
+ // 灞曞紑琛�
+ const expandChange = async (row, expandedRows) => {
+ if (expandedRows.length > 0) {
+ expandedRowKeys.value = [];
try {
- const purchaseNoRes = await createPurchaseNo();
- if (purchaseNoRes?.data) {
- form.value.purchaseContractNumber = purchaseNoRes.data;
+ const res = await productList({ salesLedgerId: row.id, type: 2 });
+ const index = tableData.value.findIndex(item => item.id === row.id);
+ if (index > -1) {
+ tableData.value[index].children = res.data || [];
+ expandedRowKeys.value.push(row.id);
}
} catch (error) {
- console.error('鐢熸垚閲囪喘鍚堝悓鍙峰け璐�:', error);
- proxy.$modal.msgWarning('鐢熸垚閲囪喘鍚堝悓鍙峰け璐�');
+ console.error("鍔犺浇浜у搧鍒楄〃澶辫触:", error);
+ proxy.$modal.msgError("鍔犺浇浜у搧鍒楄〃澶辫触");
+ // 灞曞紑澶辫触鏃讹紝绉婚櫎灞曞紑鐘舵��
+ const index = expandedRows.findIndex(item => item.id === row.id);
+ if (index > -1) {
+ expandedRows.splice(index, 1);
+ }
}
- } else if (type === "edit" && row?.id) {
- // 缂栬緫鏃跺姞杞芥暟鎹�
- currentId.value = row.id;
- try {
- const purchaseRes = await getPurchaseById({ id: row.id, type: 2 });
- form.value = { ...purchaseRes };
- productData.value = purchaseRes.productData || [];
- fileList.value = purchaseRes.salesLedgerFiles || [];
- } catch (error) {
- console.error('鍔犺浇閲囪喘鍙拌处鏁版嵁澶辫触:', error);
- proxy.$modal.msgError('鍔犺浇鏁版嵁澶辫触');
- return;
- }
- }
-
- dialogFormVisible.value = true;
- } catch (error) {
- console.error('鎵撳紑琛ㄥ崟澶辫触:', error);
- proxy.$modal.msgError('鍔犺浇鍩虹鏁版嵁澶辫触');
- }
-};
-// 涓婁紶鍓嶆牎妫�
-function handleBeforeUpload(file) {
- // 鏍℃鏂囦欢澶у皬
- if (file.size > 1024 * 1024 * 10) {
- proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB!");
- return false;
- }
- proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
- return true;
-}
-// 涓婁紶澶辫触
-function handleUploadError(err) {
- proxy.$modal.msgError("涓婁紶鏂囦欢澶辫触");
- proxy.$modal.closeLoading();
-}
-// 涓婁紶鎴愬姛鍥炶皟
-function handleUploadSuccess(res, file, uploadFiles) {
- proxy.$modal.closeLoading();
- if (res.code === 200) {
- file.tempId = res.data.tempId;
- proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
- } else {
- proxy.$modal.msgError(res.msg);
- proxy.$refs.fileUpload.handleRemove(file);
- }
-}
-// 绉婚櫎鏂囦欢
-async function handleRemove(file) {
- if (!file?.id) {
- return;
- }
-
- if (file.size > 1024 * 1024 * 10) {
- // 浠呭墠绔竻鐞嗭紝涓嶈皟鐢ㄥ垹闄ゆ帴鍙e拰鎻愮ず
- return;
- }
-
- if (operationType.value === "edit" && file.id) {
- try {
- await delLedgerFile([file.id]);
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- } catch (error) {
- console.error('鍒犻櫎鏂囦欢澶辫触:', error);
- proxy.$modal.msgError("鍒犻櫎鏂囦欢澶辫触");
- }
- }
-}
-// 鎻愪氦琛ㄥ崟
-const submitForm = async () => {
- try {
- const valid = await proxy.$refs["formRef"].validate().catch(() => false);
- if (!valid) {
- return;
- }
-
- if (!productData.value || productData.value.length === 0) {
- proxy.$modal.msgWarning("璇锋坊鍔犱骇鍝佷俊鎭�");
- return;
- }
-
- form.value.productData = proxy.HaveJson(productData.value);
- form.value.tempFileIds = fileList.value
- .filter(item => item.tempId)
- .map((item) => item.tempId);
- form.value.type = 2;
-
- try {
- await addOrEditPurchase(form.value);
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- getList();
- } catch (error) {
- console.error('鎻愪氦琛ㄥ崟澶辫触:', error);
- proxy.$modal.msgError("鎻愪氦澶辫触锛岃绋嶅悗閲嶈瘯");
- }
- } catch (error) {
- console.error('琛ㄥ崟楠岃瘉澶辫触:', error);
- }
-};
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
-};
-// 鎵撳紑浜у搧寮规
-const openProductForm = (type, row, index) => {
- productOperationType.value = type;
- productOperationIndex.value = index;
- productForm.value = {};
- proxy.resetForm("productFormRef");
- if (type === "edit") {
- productForm.value = { ...row };
- }
- productFormVisible.value = true;
- getProductOptions();
-};
-const getProductOptions = async () => {
- try {
- const res = await productTreeList();
- productOptions.value = convertIdToValue(res);
- } catch (error) {
- console.error('鍔犺浇浜у搧閫夐」澶辫触:', error);
- proxy.$modal.msgError('鍔犺浇浜у搧閫夐」澶辫触');
- }
-};
-const getModels = async (value) => {
- if (value) {
- productForm.value.productCategory = findNodeById(productOptions.value, value) || "";
- try {
- const res = await modelList({ id: value });
- modelOptions.value = res || [];
- } catch (error) {
- console.error('鍔犺浇瑙勬牸鍨嬪彿澶辫触:', error);
- proxy.$modal.msgError('鍔犺浇瑙勬牸鍨嬪彿澶辫触');
- modelOptions.value = [];
- }
- } else {
- productForm.value.productCategory = "";
- modelOptions.value = [];
- }
-};
-const getProductModel = (value) => {
- const index = modelOptions.value.findIndex((item) => item.id === value);
- if (index !== -1) {
- productForm.value.specificationModel = modelOptions.value[index].model;
- productForm.value.unit = modelOptions.value[index].unit;
- } else {
- productForm.value.specificationModel = null;
- productForm.value.unit = null;
- }
-};
-const findNodeById = (nodes, productId) => {
- for (let i = 0; i < nodes.length; i++) {
- if (nodes[i].value === productId) {
- return nodes[i].label; // 鎵惧埌鑺傜偣锛岃繑鍥炶鑺傜偣鐨刲abel
- }
- if (nodes[i].children && nodes[i].children.length > 0) {
- const foundNode = findNodeById(nodes[i].children, productId);
- if (foundNode) {
- return foundNode; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝鐩存帴杩斿洖锛堝凡缁忔槸label瀛楃涓诧級
- }
- }
- }
- return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
-};
-function convertIdToValue(data) {
- return data.map((item) => {
- const { id, children, ...rest } = item;
- const newItem = {
- ...rest,
- value: id, // 灏� id 鏀逛负 value
- };
- if (children && children.length > 0) {
- newItem.children = convertIdToValue(children);
- }
-
- return newItem;
- });
-}
-// 鎻愪氦浜у搧琛ㄥ崟
-const submitProduct = async () => {
- try {
- const valid = await proxy.$refs["productFormRef"].validate().catch(() => false);
- if (!valid) {
- return;
- }
-
- if (operationType.value === "edit") {
- await submitProductEdit();
} else {
- if (productOperationType.value === "add") {
- productData.value.push({ ...productForm.value });
- } else {
- productData.value[productOperationIndex.value] = {
- ...productForm.value,
- };
- }
- closeProductDia();
+ expandedRowKeys.value = [];
}
- } catch (error) {
- console.error('鎻愪氦浜у搧琛ㄥ崟澶辫触:', error);
- }
-};
-
-const submitProductEdit = async () => {
- try {
- productForm.value.salesLedgerId = currentId.value;
- productForm.value.type = 2;
- await addOrUpdateSalesLedgerProduct(productForm.value);
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeProductDia();
-
- // 閲嶆柊鍔犺浇浜у搧鏁版嵁
+ };
+ // 涓昏〃鍚堣鏂规硶
+ const summarizeMainTable = param => {
+ return proxy.summarizeTable(param, ["contractAmount"]);
+ };
+ // 瀛愯〃鍚堣鏂规硶
+ const summarizeProTable = param => {
+ return proxy.summarizeTable(param, [
+ "taxInclusiveUnitPrice",
+ "taxInclusiveTotalPrice",
+ "taxExclusiveTotalPrice",
+ ]);
+ };
+ // 鎵撳紑寮规
+ const openForm = async (type, row) => {
+ await getTemplateList();
+ operationType.value = type;
+ form.value = {};
+ productData.value = [];
+ fileList.value = [];
+ templateName.value = "";
+ filterInputValue.value = "";
+ isTemplateNameDuplicate.value = false;
try {
- const res = await getPurchaseById({ id: currentId.value, type: 2 });
- productData.value = res.productData || [];
- } catch (error) {
- console.error('閲嶆柊鍔犺浇浜у搧鏁版嵁澶辫触:', error);
- }
- } catch (error) {
- console.error('鎻愪氦浜у搧缂栬緫澶辫触:', error);
- proxy.$modal.msgError("鎻愪氦澶辫触锛岃绋嶅悗閲嶈瘯");
- }
-};
-// 鍒犻櫎浜у搧
-const deleteProduct = async () => {
- if (productSelectedRows.value.length === 0) {
- proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
- return;
- }
-
- if (operationType.value === "add") {
- // 鏂板妯″紡涓嬶紝鐩存帴浠庡墠绔暟鎹腑鍒犻櫎
- productSelectedRows.value.forEach((selectedRow) => {
- const index = productData.value.findIndex(
- (product) => product.id === selectedRow.id
+ // 骞惰鍔犺浇鍩虹鏁版嵁
+ const [userRes, salesRes, supplierRes] = await Promise.all([
+ userListNoPage(),
+ getSalesNo(),
+ getOptions(),
+ ]);
+
+ userList.value = userRes.data || [];
+ salesContractList.value = salesRes || [];
+ // 渚涘簲鍟嗚繃婊ゅ嚭isWhite=0 鐨勬暟鎹�
+ supplierList.value = (supplierRes.data || []).filter(
+ item => item.isWhite === 0
);
- if (index !== -1) {
- productData.value.splice(index, 1);
+
+ // 璁剧疆榛樿鍊�
+ form.value.recorderId = userStore.id;
+ form.value.entryDate = getCurrentDate();
+
+ if (type === "add") {
+ // 鏂板鏃剁敓鎴愰噰璐悎鍚屽彿
+ try {
+ const purchaseNoRes = await createPurchaseNo();
+ if (purchaseNoRes?.data) {
+ form.value.purchaseContractNumber = purchaseNoRes.data;
+ }
+ } catch (error) {
+ console.error("鐢熸垚閲囪喘鍚堝悓鍙峰け璐�:", error);
+ proxy.$modal.msgWarning("鐢熸垚閲囪喘鍚堝悓鍙峰け璐�");
+ }
+ } else if (type === "edit" && row?.id) {
+ // 缂栬緫鏃跺姞杞芥暟鎹�
+ currentId.value = row.id;
+ try {
+ const purchaseRes = await getPurchaseById({ id: row.id, type: 2 });
+ form.value = { ...purchaseRes };
+ productData.value = purchaseRes.productData || [];
+ fileList.value = purchaseRes.salesLedgerFiles || [];
+ } catch (error) {
+ console.error("鍔犺浇閲囪喘鍙拌处鏁版嵁澶辫触:", error);
+ proxy.$modal.msgError("鍔犺浇鏁版嵁澶辫触");
+ return;
+ }
+ }
+
+ if (form.value.salesLedgerId == -1) {
+ form.value.salesLedgerId = null;
+ }
+ console.log(form.value, "form.value===========");
+ dialogFormVisible.value = true;
+ } catch (error) {
+ console.error("鎵撳紑琛ㄥ崟澶辫触:", error);
+ proxy.$modal.msgError("鍔犺浇鍩虹鏁版嵁澶辫触");
+ }
+ };
+ // 涓婁紶鍓嶆牎妫�
+ function handleBeforeUpload(file) {
+ // 鏍℃鏂囦欢澶у皬
+ if (file.size > 1024 * 1024 * 10) {
+ proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB!");
+ return false;
+ }
+ proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
+ return true;
+ }
+ // 涓婁紶澶辫触
+ function handleUploadError(err) {
+ proxy.$modal.msgError("涓婁紶鏂囦欢澶辫触");
+ proxy.$modal.closeLoading();
+ }
+ // 涓婁紶鎴愬姛鍥炶皟
+ function handleUploadSuccess(res, file, uploadFiles) {
+ proxy.$modal.closeLoading();
+ if (res.code === 200) {
+ file.tempId = res.data.tempId;
+ proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
+ } else {
+ proxy.$modal.msgError(res.msg);
+ proxy.$refs.fileUpload.handleRemove(file);
+ }
+ }
+ // 绉婚櫎鏂囦欢
+ async function handleRemove(file) {
+ if (!file?.id) {
+ return;
+ }
+ console.log("handleRemove", file.id);
+ if (file.size > 1024 * 1024 * 10) {
+ // 浠呭墠绔竻鐞嗭紝涓嶈皟鐢ㄥ垹闄ゆ帴鍙e拰鎻愮ず
+ return;
+ }
+
+ if (operationType.value === "edit" && file.id) {
+ try {
+ await delLedgerFile([file.id]);
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+ } catch (error) {
+ console.error("鍒犻櫎鏂囦欢澶辫触:", error);
+ proxy.$modal.msgError("鍒犻櫎鏂囦欢澶辫触");
+ }
+ }
+ }
+ // 鎻愪氦琛ㄥ崟
+ const submitForm = () => {
+ proxy.$refs["formRef"].validate(valid => {
+ if (valid) {
+ if (productData.value.length > 0) {
+ form.value.productData = proxy.HaveJson(productData.value);
+ } else {
+ proxy.$modal.msgWarning("璇锋坊鍔犱骇鍝佷俊鎭�");
+ return;
+ }
+ let tempFileIds = [];
+ if (fileList.value.length > 0) {
+ tempFileIds = fileList.value.map(item => item.tempId);
+ }
+ form.value.tempFileIds = tempFileIds;
+ form.value.type = 2;
+
+ // 濡傛灉salesLedgerId涓虹┖锛屽垯涓嶄紶閫抯alesContractNo
+ if (!form.value.salesLedgerId) {
+ form.value.salesContractNo = "";
+ }
+
+ addOrEditPurchase(form.value).then(res => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeDia();
+ getList();
+ });
}
});
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- } else {
- // 缂栬緫妯″紡涓嬶紝闇�瑕佽皟鐢ㄦ帴鍙e垹闄�
- const ids = productSelectedRows.value
- .filter(item => item.id)
- .map((item) => item.id);
-
- if (ids.length === 0) {
- proxy.$modal.msgWarning("璇烽�夋嫨鏈夋晥鐨勬暟鎹�");
+ };
+ // 鍏抽棴寮规
+ const closeDia = () => {
+ proxy.resetForm("formRef");
+ dialogFormVisible.value = false;
+ };
+ // 鎵撳紑浜у搧寮规
+ const openProductForm = (type, row, index) => {
+ productOperationType.value = type;
+ productOperationIndex.value = index;
+ productForm.value = {};
+ proxy.resetForm("productFormRef");
+ if (type === "edit") {
+ productForm.value = { ...row };
+ }
+ productFormVisible.value = true;
+ getProductOptions();
+ };
+ const getProductOptions = () => {
+ productTreeList().then(res => {
+ productOptions.value = convertIdToValue(res);
+ });
+ };
+ const getModels = value => {
+ if (value) {
+ productForm.value.productCategory =
+ findNodeById(productOptions.value, value) || "";
+ modelList({ id: value }).then(res => {
+ modelOptions.value = res;
+ });
+ } else {
+ productForm.value.productCategory = "";
+ modelOptions.value = [];
+ }
+ };
+ const getProductModel = value => {
+ const index = modelOptions.value.findIndex(item => item.id === value);
+ if (index !== -1) {
+ productForm.value.specificationModel = modelOptions.value[index].model;
+ productForm.value.unit = modelOptions.value[index].unit;
+ } else {
+ productForm.value.specificationModel = null;
+ productForm.value.unit = null;
+ }
+ };
+ const findNodeById = (nodes, productId) => {
+ for (let i = 0; i < nodes.length; i++) {
+ if (nodes[i].value === productId) {
+ return nodes[i].label; // 鎵惧埌鑺傜偣锛岃繑鍥炶鑺傜偣鐨刲abel
+ }
+ if (nodes[i].children && nodes[i].children.length > 0) {
+ const foundNode = findNodeById(nodes[i].children, productId);
+ if (foundNode) {
+ return foundNode; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝鐩存帴杩斿洖锛堝凡缁忔槸label瀛楃涓诧級
+ }
+ }
+ }
+ return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
+ };
+ function convertIdToValue(data) {
+ return data.map(item => {
+ const { id, children, ...rest } = item;
+ const newItem = {
+ ...rest,
+ value: id, // 灏� id 鏀逛负 value
+ };
+ if (children && children.length > 0) {
+ newItem.children = convertIdToValue(children);
+ }
+
+ return newItem;
+ });
+ }
+ // 鎻愪氦浜у搧琛ㄥ崟
+ const submitProduct = () => {
+ proxy.$refs["productFormRef"].validate(valid => {
+ if (valid) {
+ if (operationType.value === "edit") {
+ submitProductEdit();
+ } else {
+ if (productOperationType.value === "add") {
+ productData.value.push({ ...productForm.value });
+ console.log("productData.value---", productData.value);
+ } else {
+ productData.value[productOperationIndex.value] = {
+ ...productForm.value,
+ };
+ }
+ closeProductDia();
+ }
+ }
+ });
+ };
+ const submitProductEdit = () => {
+ productForm.value.salesLedgerId = currentId.value;
+ productForm.value.type = 2;
+ addOrUpdateSalesLedgerProduct(productForm.value).then(res => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeProductDia();
+ getPurchaseById({ id: currentId.value, type: 2 }).then(res => {
+ productData.value = res.productData;
+ });
+ });
+ };
+ // 鍒犻櫎浜у搧
+ const deleteProduct = () => {
+ if (productSelectedRows.value.length === 0) {
+ proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
return;
}
-
- try {
- await ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎纭", {
+ if (operationType.value === "add") {
+ productSelectedRows.value.forEach(selectedRow => {
+ const index = productData.value.findIndex(
+ product => product.id === selectedRow.id
+ );
+ if (index !== -1) {
+ productData.value.splice(index, 1);
+ }
+ });
+ } else {
+ let ids = [];
+ if (productSelectedRows.value.length > 0) {
+ ids = productSelectedRows.value.map(item => item.id);
+ }
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
confirmButtonText: "纭",
cancelButtonText: "鍙栨秷",
type: "warning",
+ })
+ .then(() => {
+ delProduct(ids).then(res => {
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+ closeProductDia();
+ getSalesLedgerWithProducts({ id: currentId.value, type: 2 }).then(
+ res => {
+ productData.value = res.productData;
+ }
+ );
+ });
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
+ }
+ };
+ // 鍏抽棴浜у搧寮规
+ const closeProductDia = () => {
+ proxy.resetForm("productFormRef");
+ productFormVisible.value = false;
+ };
+ // 瀵煎嚭
+ const handleOut = () => {
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ proxy.download("/purchase/ledger/export", {}, "閲囪喘鍙拌处.xlsx");
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
});
-
- await delProduct(ids);
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- closeProductDia();
-
- // 閲嶆柊鍔犺浇浜у搧鏁版嵁
- try {
- const res = await getSalesLedgerWithProducts({ id: currentId.value, type: 2 });
- productData.value = res.productData || [];
- } catch (error) {
- console.error('閲嶆柊鍔犺浇浜у搧鏁版嵁澶辫触:', error);
- }
- } catch (error) {
- if (error !== 'cancel') {
- console.error('鍒犻櫎浜у搧澶辫触:', error);
- proxy.$modal.msgError("鍒犻櫎澶辫触锛岃绋嶅悗閲嶈瘯");
- }
- }
- }
-};
-// 鍏抽棴浜у搧寮规
-const closeProductDia = () => {
- proxy.resetForm("productFormRef");
- productFormVisible.value = false;
-};
-// 瀵煎嚭
-const handleOut = async () => {
- try {
- await ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭纭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- });
- proxy.download("/purchase/ledger/export", {}, "閲囪喘鍙拌处.xlsx");
- } catch (error) {
- if (error !== 'cancel') {
- console.error('瀵煎嚭澶辫触:', error);
- proxy.$modal.msgError("瀵煎嚭澶辫触锛岃绋嶅悗閲嶈瘯");
- }
- }
-};
-
-// 鍒犻櫎
-const handleDelete = async () => {
- if (selectedRows.value.length === 0) {
- proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
- return;
- }
-
- // 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
- const unauthorizedData = selectedRows.value.filter(item => item.recorderName !== userStore.nickName);
- if (unauthorizedData.length > 0) {
- proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
- return;
- }
-
- const ids = selectedRows.value
- .filter(item => item.id)
- .map((item) => item.id);
-
- if (ids.length === 0) {
- proxy.$modal.msgWarning("璇烽�夋嫨鏈夋晥鐨勬暟鎹�");
- return;
- }
-
- try {
- await ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎纭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- });
-
- await delPurchase(ids);
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- } catch (error) {
- if (error !== 'cancel') {
- console.error('鍒犻櫎澶辫触:', error);
- proxy.$modal.msgError("鍒犻櫎澶辫触锛岃绋嶅悗閲嶈瘯");
- }
- }
-};
-const mathNum = () => {
- if (!productForm.value.taxRate) {
- proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
- return;
- }
- if (!productForm.value.taxInclusiveUnitPrice) {
- return;
- }
- if (!productForm.value.quantity) {
- return;
- }
- // 鍚◣鎬讳环璁$畻
- productForm.value.taxInclusiveTotalPrice =
- proxy.calculateTaxIncludeTotalPrice(
- productForm.value.taxInclusiveUnitPrice,
- productForm.value.quantity
+ };
+ // 鍒犻櫎
+ const handleDelete = () => {
+ let ids = [];
+ if (selectedRows.value.length > 0) {
+ // 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
+ const unauthorizedData = selectedRows.value.filter(
+ item => item.recorderName !== userStore.nickName
);
- if (productForm.value.taxRate) {
- // 涓嶅惈绋庢�讳环璁$畻
- productForm.value.taxExclusiveTotalPrice =
- proxy.calculateTaxExclusiveTotalPrice(
- productForm.value.taxInclusiveTotalPrice,
- productForm.value.taxRate
- );
- }
-};
-const reverseMathNum = (field) => {
- if (!productForm.value.taxRate) {
- proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
- return;
- }
- const taxRate = Number(productForm.value.taxRate);
- if (!taxRate) return;
- if (field === 'taxInclusiveTotalPrice') {
- // 宸茬煡鍚◣鎬讳环鍜屾暟閲忥紝鍙嶇畻鍚◣鍗曚环
- if (productForm.value.quantity) {
- productForm.value.taxInclusiveUnitPrice =
- (Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.quantity)).toFixed(2);
+ if (unauthorizedData.length > 0) {
+ proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
+ return;
+ }
+ ids = selectedRows.value.map(item => item.id);
+ } else {
+ proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+ return;
}
- // 宸茬煡鍚◣鎬讳环鍜屽惈绋庡崟浠凤紝鍙嶇畻鏁伴噺
- else if (productForm.value.taxInclusiveUnitPrice) {
- productForm.value.quantity =
- (Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.taxInclusiveUnitPrice)).toFixed(2);
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ delPurchase(ids).then(res => {
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+ getList();
+ });
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
+ };
+ // 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
+ function getCurrentDate() {
+ const today = new Date();
+ const year = today.getFullYear();
+ const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
+ const day = String(today.getDate()).padStart(2, "0");
+ return `${year}-${month}-${day}`;
+ }
+ const mathNum = () => {
+ if (!productForm.value.taxRate) {
+ proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
+ return;
}
- // 鍙嶇畻涓嶅惈绋庢�讳环
- productForm.value.taxExclusiveTotalPrice =
- (Number(productForm.value.taxInclusiveTotalPrice) / (1 + taxRate / 100)).toFixed(2);
- } else if (field === 'taxExclusiveTotalPrice') {
- // 鍙嶇畻鍚◣鎬讳环
+ if (!productForm.value.taxInclusiveUnitPrice) {
+ return;
+ }
+ if (!productForm.value.quantity) {
+ return;
+ }
+ // 鍚◣鎬讳环璁$畻
productForm.value.taxInclusiveTotalPrice =
- (Number(productForm.value.taxExclusiveTotalPrice) * (1 + taxRate / 100)).toFixed(2);
- // 宸茬煡鏁伴噺锛屽弽绠楀惈绋庡崟浠�
- if (productForm.value.quantity) {
- productForm.value.taxInclusiveUnitPrice =
- (Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.quantity)).toFixed(2);
+ proxy.calculateTaxIncludeTotalPrice(
+ productForm.value.taxInclusiveUnitPrice,
+ productForm.value.quantity
+ );
+ if (productForm.value.taxRate) {
+ // 涓嶅惈绋庢�讳环璁$畻
+ productForm.value.taxExclusiveTotalPrice =
+ proxy.calculateTaxExclusiveTotalPrice(
+ productForm.value.taxInclusiveTotalPrice,
+ productForm.value.taxRate
+ );
}
- // 宸茬煡鍚◣鍗曚环锛屽弽绠楁暟閲�
- else if (productForm.value.taxInclusiveUnitPrice) {
- productForm.value.quantity =
- (Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.taxInclusiveUnitPrice)).toFixed(2);
+ };
+ const reverseMathNum = field => {
+ if (!productForm.value.taxRate) {
+ proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
+ return;
}
- }
-};
-// 閿�鍞悎鍚岄�夋嫨鏀瑰彉鏂规硶
-const salesLedgerChange = async (row) => {
- const index = salesContractList.value.findIndex((item) => item.id === row);
- if (index > -1) {
- form.value.projectName = salesContractList.value[index].projectName;
- await querygProductInfoByContractNo();
- }
-};
+ const taxRate = Number(productForm.value.taxRate);
+ if (!taxRate) return;
-const querygProductInfoByContractNo = async () => {
- const { code, data } = await getProductInfoByContractNo({
- contractNo: form.value.salesLedgerId,
+ // 纭繚杈撳叆鍊间笉涓鸿礋鏁�
+ if (
+ field === "taxInclusiveTotalPrice" ||
+ field === "taxExclusiveTotalPrice"
+ ) {
+ const value = Number(productForm.value[field]);
+ if (value < 0) {
+ productForm.value[field] = "0";
+ proxy.$modal.msgWarning("鍊间笉鑳藉皬浜�0");
+ return;
+ }
+ }
+
+ if (field === "taxInclusiveTotalPrice") {
+ // 宸茬煡鍚◣鎬讳环鍜屾暟閲忥紝鍙嶇畻鍚◣鍗曚环
+ if (productForm.value.quantity) {
+ productForm.value.taxInclusiveUnitPrice = (
+ Number(productForm.value.taxInclusiveTotalPrice) /
+ Number(productForm.value.quantity)
+ ).toFixed(2);
+ // 纭繚缁撴灉涓嶄负璐熸暟
+ if (Number(productForm.value.taxInclusiveUnitPrice) < 0) {
+ productForm.value.taxInclusiveUnitPrice = "0";
+ }
+ }
+ // 宸茬煡鍚◣鎬讳环鍜屽惈绋庡崟浠凤紝鍙嶇畻鏁伴噺
+ else if (productForm.value.taxInclusiveUnitPrice) {
+ productForm.value.quantity = (
+ Number(productForm.value.taxInclusiveTotalPrice) /
+ Number(productForm.value.taxInclusiveUnitPrice)
+ ).toFixed(2);
+ // 纭繚缁撴灉涓嶄负璐熸暟
+ if (Number(productForm.value.quantity) < 0) {
+ productForm.value.quantity = "0";
+ }
+ }
+ // 鍙嶇畻涓嶅惈绋庢�讳环
+ productForm.value.taxExclusiveTotalPrice = (
+ Number(productForm.value.taxInclusiveTotalPrice) /
+ (1 + taxRate / 100)
+ ).toFixed(2);
+ // 纭繚缁撴灉涓嶄负璐熸暟
+ if (Number(productForm.value.taxExclusiveTotalPrice) < 0) {
+ productForm.value.taxExclusiveTotalPrice = "0";
+ }
+ } else if (field === "taxExclusiveTotalPrice") {
+ // 鍙嶇畻鍚◣鎬讳环
+ productForm.value.taxInclusiveTotalPrice = (
+ Number(productForm.value.taxExclusiveTotalPrice) *
+ (1 + taxRate / 100)
+ ).toFixed(2);
+ // 纭繚缁撴灉涓嶄负璐熸暟
+ if (Number(productForm.value.taxInclusiveTotalPrice) < 0) {
+ productForm.value.taxInclusiveTotalPrice = "0";
+ }
+ // 宸茬煡鏁伴噺锛屽弽绠楀惈绋庡崟浠�
+ if (productForm.value.quantity) {
+ productForm.value.taxInclusiveUnitPrice = (
+ Number(productForm.value.taxInclusiveTotalPrice) /
+ Number(productForm.value.quantity)
+ ).toFixed(2);
+ // 纭繚缁撴灉涓嶄负璐熸暟
+ if (Number(productForm.value.taxInclusiveUnitPrice) < 0) {
+ productForm.value.taxInclusiveUnitPrice = "0";
+ }
+ }
+ // 宸茬煡鍚◣鍗曚环锛屽弽绠楁暟閲�
+ else if (productForm.value.taxInclusiveUnitPrice) {
+ productForm.value.quantity = (
+ Number(productForm.value.taxInclusiveTotalPrice) /
+ Number(productForm.value.taxInclusiveUnitPrice)
+ ).toFixed(2);
+ // 纭繚缁撴灉涓嶄负璐熸暟
+ if (Number(productForm.value.quantity) < 0) {
+ productForm.value.quantity = "0";
+ }
+ }
+ }
+ };
+ // 閿�鍞悎鍚岄�夋嫨鏀瑰彉鏂规硶
+ const salesLedgerChange = async row => {
+ console.log("row", row);
+ var index = salesContractList.value.findIndex(item => item.id == row);
+ console.log("index", index);
+ if (index > -1) {
+ await querygProductInfoByContractNo();
+ }
+ };
+
+ const querygProductInfoByContractNo = async () => {
+ const { code, data } = await getProductInfoByContractNo({
+ contractNo: form.value.salesLedgerId,
+ });
+ if (code == 200) {
+ productData.value = data;
+ }
+ };
+
+ const fileListRef = ref(null);
+ const downLoadFile = row => {
+ fileListRef.value.open(row.salesLedgerFiles);
+ };
+
+ // 鏄剧ず浜岀淮鐮�
+ const showQRCode = async row => {
+ try {
+ // 鏋勫缓浜岀淮鐮佸唴瀹癸紝鍙寘鍚噰璐悎鍚屽彿锛堢函鏂囨湰锛�
+ const qrContent = row.purchaseContractNumber || "";
+ // 妫�鏌ュ唴瀹规槸鍚︿负绌�
+ if (!qrContent || qrContent.trim() === "") {
+ proxy.$modal.msgWarning("璇ヨ娌℃湁閲囪喘鍚堝悓鍙凤紝鏃犳硶鐢熸垚浜岀淮鐮�");
+ return;
+ }
+ qrCodeUrl.value = await QRCode.toDataURL(qrContent, {
+ width: 200,
+ margin: 2,
+ color: {
+ dark: "#000000",
+ light: "#FFFFFF",
+ },
+ });
+ qrCodeDialogVisible.value = true;
+ } catch (error) {
+ console.error("鐢熸垚浜岀淮鐮佸け璐�:", error);
+ proxy.$modal.msgError("鐢熸垚浜岀淮鐮佸け璐ワ細" + error.message);
+ }
+ };
+
+ // 涓嬭浇浜岀淮鐮�
+ const downloadQRCode = () => {
+ if (!qrCodeUrl.value) {
+ proxy.$modal.msgWarning("浜岀淮鐮佹湭鐢熸垚");
+ return;
+ }
+
+ const a = document.createElement("a");
+ a.href = qrCodeUrl.value;
+ a.download = `閲囪喘鍚堝悓鍙蜂簩缁寸爜_${new Date().getTime()}.png`;
+ document.body.appendChild(a);
+ a.click();
+ document.body.removeChild(a);
+ proxy.$modal.msgSuccess("涓嬭浇鎴愬姛");
+ };
+
+ // 鎵爜鏂板瀵硅瘽妗嗙浉鍏冲彉閲�
+ const scanAddDialogVisible = ref(false);
+ const scanAddForm = reactive({
+ scanContent: "",
+ purchaseContractNumber: "",
+ supplierName: "",
+ projectName: "",
+ contractAmount: "",
+ paymentMethod: "",
+ recorderName: "",
+ scanRemark: "",
});
- if (code == 200) {
- productData.value = data;
+ const scanAddRules = {
+ purchaseContractNumber: [
+ { required: true, message: "璇疯緭鍏ラ噰璐悎鍚屽彿", trigger: "blur" },
+ ],
+ supplierName: [
+ { required: true, message: "璇疯緭鍏ヤ緵搴斿晢鍚嶇О", trigger: "blur" },
+ ],
+ projectName: [{ required: true, message: "璇疯緭鍏ラ」鐩悕绉�", trigger: "blur" }],
+ };
+
+ // 鎵爜鐧昏瀵硅瘽妗嗙浉鍏冲彉閲�
+ const scanDialogVisible = ref(false);
+ const scanForm = reactive({
+ purchaseContractNumber: "",
+ supplierName: "",
+ projectName: "",
+ scanTime: "",
+ scannerName: "",
+ scanStatus: "鏈壂鐮�",
+ scanRemark: "",
+ });
+ const scanRules = {
+ scanRemark: [{ required: true, message: "璇疯緭鍏ユ壂鐮佸娉�", trigger: "blur" }],
+ };
+ const scanRecords = ref([]);
+
+ // 鎵撳紑鎵爜鏂板瀵硅瘽妗�
+ const openScanAddDialog = () => {
+ scanAddForm.scanContent = "";
+ scanAddForm.purchaseContractNumber = "";
+ scanAddForm.supplierName = "";
+ scanAddForm.projectName = "";
+ scanAddForm.contractAmount = "";
+ scanAddForm.paymentMethod = "";
+ scanAddForm.recorderName = userStore.nickName;
+ scanAddForm.scanRemark = "";
+ scanAddDialogVisible.value = true;
+ };
+
+ // 瑙f瀽鎵爜鍐呭锛堟ā鎷熻В鏋愪簩缁寸爜鏁版嵁锛�
+ const parseScanContent = content => {
+ if (!content) return;
+
+ // 妯℃嫙瑙f瀽浜岀淮鐮佸唴瀹癸紝杩欓噷鍙互鏍规嵁瀹為檯闇�姹傝皟鏁磋В鏋愰�昏緫
+ // 鍋囪鎵爜鍐呭鏍煎紡涓猴細鍚堝悓鍙穦渚涘簲鍟唡閲戦|浠樻鏂瑰紡
+ const parts = content.split("|");
+ if (parts.length >= 2) {
+ scanAddForm.purchaseContractNumber = parts[0] || "";
+ scanAddForm.supplierName = parts[1] || "";
+ scanAddForm.contractAmount = parts[2] || "";
+ scanAddForm.paymentMethod = parts[3] || "";
+ scanAddForm.projectName = parts[4] || "";
+ // scanAddForm.contractAmount = parts[3] || "";
+ // scanAddForm.paymentMethod = parts[4] || "";
+ }
+ };
+
+ // 鍏抽棴鎵爜鏂板瀵硅瘽妗�
+ const closeScanAddDialog = () => {
+ scanAddDialogVisible.value = false;
+ proxy.resetForm("scanAddFormRef");
+ };
+
+ // 鎻愪氦鎵爜鏂板
+ const submitScanAdd = () => {
+ proxy.$refs["scanAddFormRef"].validate(valid => {
+ if (valid) {
+ // 鏋勫缓鏂板鏁版嵁
+ const newData = {
+ purchaseContractNumber: scanAddForm.purchaseContractNumber,
+ supplierName: scanAddForm.supplierName,
+ projectName: scanAddForm.projectName,
+ contractAmount: scanAddForm.contractAmount,
+ paymentMethod: scanAddForm.paymentMethod,
+ recorderName: scanAddForm.recorderName,
+ entryDate: getCurrentDate(),
+ remark: scanAddForm.scanRemark,
+ type: 2,
+ };
+
+ // 妯℃嫙鏂板鎴愬姛
+ proxy.$modal.msgSuccess("鎵爜鏂板鎴愬姛锛�");
+ closeScanAddDialog();
+
+ // 鍙互閫夋嫨鏄惁鍒锋柊鍒楄〃
+ // getList();
+ }
+ });
+ };
+
+ // 鎵撳紑鎵爜鐧昏瀵硅瘽妗�
+ const openScanDialog = row => {
+ scanForm.purchaseContractNumber = row.purchaseContractNumber;
+ scanForm.supplierName = row.supplierName;
+ scanForm.projectName = row.projectName;
+ scanForm.scanTime = getCurrentDateTime();
+ scanForm.scannerName = userStore.nickName;
+ scanForm.scanStatus = "鏈壂鐮�";
+ scanForm.scanRemark = "";
+ scanRecords.value = [];
+ scanDialogVisible.value = true;
+ };
+
+ // 鍏抽棴鎵爜鐧昏瀵硅瘽妗�
+ const closeScanDialog = () => {
+ scanDialogVisible.value = false;
+ proxy.resetForm("scanFormRef");
+ };
+
+ // 鎻愪氦鎵爜鐧昏
+ const submitScan = () => {
+ proxy.$refs["scanFormRef"].validate(valid => {
+ if (valid) {
+ // 娣诲姞鎵爜璁板綍
+ scanRecords.value.push({
+ ...scanForm,
+ id: Date.now(), // 妯℃嫙ID
+ scanTime: getCurrentDateTime(),
+ });
+ scanForm.scanStatus = "宸叉壂鐮�";
+ scanForm.scanRemark = scanForm.scanRemark || "鏃�";
+ proxy.$modal.msgSuccess("鎵爜鐧昏鎴愬姛锛�");
+ closeScanDialog();
+ }
+ });
+ };
+
+ // 鑾峰彇褰撳墠鏃ユ湡鏃堕棿
+ function getCurrentDateTime() {
+ const now = new Date();
+ const year = now.getFullYear();
+ const month = String(now.getMonth() + 1).padStart(2, "0");
+ const day = String(now.getDate()).padStart(2, "0");
+ const hours = String(now.getHours()).padStart(2, "0");
+ const minutes = String(now.getMinutes()).padStart(2, "0");
+ const seconds = String(now.getSeconds()).padStart(2, "0");
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
-};
-// 娣诲姞琛岀被鍚嶆柟娉�
-const tableRowClassName = ({ row }) => {
- return row.isInvalid ? 'invalid-row' : '';
-};
+ // 娣诲姞琛岀被鍚嶆柟娉�
+ const tableRowClassName = ({ row }) => {
+ return row.isInvalid ? "invalid-row" : "";
+ };
-// 鑾峰彇妯℃澘淇℃伅
-const getTemplateList =async ()=>{
- let res = await getPurchaseTemplateList()
- if(res && res.code===200 && Array.isArray(res.data)){
- templateList.value = res.data
- }
-}
+ // 鑾峰彇妯℃澘淇℃伅
+ const getTemplateList = async () => {
+ let res = await getPurchaseTemplateList();
+ if (res && res.code === 200 && Array.isArray(res.data)) {
+ templateList.value = res.data;
+ }
+ };
-onMounted(() => {
- getList();
- getTemplateList();
-
-});
+ onMounted(() => {
+ getList();
+ getTemplateList();
+ });
</script>
<style scoped lang="scss">
-.invalid-row {
- opacity: 0.6;
- background-color: #f5f7fa;
-}
-.el-row{
- justify-content: space-between;
- align-items: center
-}
-.no-arrow-select {
- --el-select-suffix-icon-color: transparent; /* 闅愯棌榛樿涓嬫媺绠ご */
-}
-.select-button-group {
- display: flex;
- align-items: center;
-}
-
+ .invalid-row {
+ opacity: 0.6;
+ background-color: #f5f7fa;
+ }
+ .el-row {
+ justify-content: space-between;
+ align-items: center;
+ }
+ .no-arrow-select {
+ --el-select-suffix-icon-color: transparent; /* 闅愯棌榛樿涓嬫媺绠ご */
+ }
+ .select-button-group {
+ display: flex;
+ align-items: center;
+ }
</style>
diff --git a/src/views/productionManagement/productionCosting/index.vue b/src/views/productionManagement/productionCosting/index.vue
index a597317..229bf04 100644
--- a/src/views/productionManagement/productionCosting/index.vue
+++ b/src/views/productionManagement/productionCosting/index.vue
@@ -181,7 +181,7 @@
type: "warning",
})
.then(() => {
- proxy.download("/basic/customer/export", {}, "鐢熶骇鏍哥畻.xlsx");
+ proxy.download("/salesLedger/productionAccounting/export", {}, "鐢熶骇鏍哥畻.xlsx");
})
.catch(() => {
proxy.$modal.msg("宸插彇娑�");
diff --git a/src/views/productionManagement/productionDispatching/components/formDia.vue b/src/views/productionManagement/productionDispatching/components/formDia.vue
index 971bc6e..e7e6e15 100644
--- a/src/views/productionManagement/productionDispatching/components/formDia.vue
+++ b/src/views/productionManagement/productionDispatching/components/formDia.vue
@@ -111,7 +111,6 @@
<script setup>
import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
import {userListNoPageByTenantId} from "@/api/system/user.js";
import {productionDispatch} from "@/api/productionManagement/productionOrder.js";
import useUserStore from "@/store/modules/user.js";
diff --git a/src/views/productionManagement/productionOrder/index.vue b/src/views/productionManagement/productionOrder/index.vue
index 9250eb8..51b42ac 100644
--- a/src/views/productionManagement/productionOrder/index.vue
+++ b/src/views/productionManagement/productionOrder/index.vue
@@ -133,7 +133,7 @@
{
label: "宸ヨ壓璺嚎缂栧彿",
prop: "processRouteCode",
- width: '140px',
+ width: '200px',
},
{
label: "闇�姹傛暟閲�",
diff --git a/src/views/productionManagement/productionReporting/components/formDia.vue b/src/views/productionManagement/productionReporting/components/formDia.vue
index 2eb1c0b..126c5b0 100644
--- a/src/views/productionManagement/productionReporting/components/formDia.vue
+++ b/src/views/productionManagement/productionReporting/components/formDia.vue
@@ -94,7 +94,6 @@
<script setup>
import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
import {userListNoPageByTenantId} from "@/api/system/user.js";
import {productionReport, productionReportUpdate} from "@/api/productionManagement/productionReporting.js";
const { proxy } = getCurrentInstance()
diff --git a/src/views/productionManagement/productionReporting/index.vue b/src/views/productionManagement/productionReporting/index.vue
index f4137af..6b543e7 100644
--- a/src/views/productionManagement/productionReporting/index.vue
+++ b/src/views/productionManagement/productionReporting/index.vue
@@ -19,21 +19,6 @@
style="width: 200px;"
@change="handleQuery" />
</el-form-item>
- <el-form-item label="宸ュ崟鐘舵��:">
- <el-select v-model="searchForm.workOrderStatus"
- placeholder="璇烽�夋嫨宸ュ崟鐘舵��"
- style="width: 140px"
- clearable>
- <el-option label="寰呯‘璁�"
- :value="1"></el-option>
- <el-option label="寰呯敓浜�"
- :value="2"></el-option>
- <el-option label="鐢熶骇涓�"
- :value="3"></el-option>
- <el-option label="宸茬敓浜�"
- :value="4"></el-option>
- </el-select>
- </el-form-item>
<el-form-item>
<el-button type="primary"
@click="handleQuery">鎼滅储</el-button>
@@ -416,7 +401,7 @@
type: "warning",
})
.then(() => {
- proxy.download("/salesLedger/work/export", {}, "鐢熶骇鎶ュ伐.xlsx");
+ proxy.download("/productionProductMain/export", {}, "鐢熶骇鎶ュ伐.xlsx");
})
.catch(() => {
proxy.$modal.msg("宸插彇娑�");
diff --git a/src/views/qualityManagement/finalInspection/components/filesDia.vue b/src/views/qualityManagement/finalInspection/components/filesDia.vue
index 66392f3..51dd78f 100644
--- a/src/views/qualityManagement/finalInspection/components/filesDia.vue
+++ b/src/views/qualityManagement/finalInspection/components/filesDia.vue
@@ -51,7 +51,6 @@
<script setup>
import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
import {Search} from "@element-plus/icons-vue";
import {
qualityInspectParamDel,
diff --git a/src/views/qualityManagement/finalInspection/components/formDia.vue b/src/views/qualityManagement/finalInspection/components/formDia.vue
index 057781c..5bd847f 100644
--- a/src/views/qualityManagement/finalInspection/components/formDia.vue
+++ b/src/views/qualityManagement/finalInspection/components/formDia.vue
@@ -27,6 +27,24 @@
<el-input v-model="form.model" placeholder="璇疯緭鍏�" clearable/>
</el-form-item>
</el-col>
+ <el-col :span="12">
+ <el-form-item label="鎸囨爣閫夋嫨锛�" prop="testStandardId">
+ <el-select
+ v-model="form.testStandardId"
+ placeholder="璇烽�夋嫨鎸囨爣"
+ clearable
+ @change="handleTestStandardChange"
+ style="width: 100%"
+ >
+ <el-option
+ v-for="item in testStandardOptions"
+ :key="item.id"
+ :label="item.standardName || item.standardNo"
+ :value="item.id"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
@@ -101,12 +119,12 @@
</template>
<script setup>
-import {ref} from "vue";
+import {ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue";
import {getOptions} from "@/api/procurementManagement/procurementLedger.js";
import {productTreeList} from "@/api/basicData/product.js";
import {qualityInspectAdd, qualityInspectUpdate} from "@/api/qualityManagement/rawMaterialInspection.js";
import {userListNoPage} from "@/api/system/user.js";
-import {qualityInspectDetailByProductId} from "@/api/qualityManagement/metricMaintenance.js";
+import {qualityInspectDetailByProductId, getQualityTestStandardParamByTestStandardId} from "@/api/qualityManagement/metricMaintenance.js";
import {qualityInspectParamInfo} from "@/api/qualityManagement/qualityInspectParam.js";
const { proxy } = getCurrentInstance()
const emit = defineEmits(['close'])
@@ -121,6 +139,7 @@
productName: "",
productId: "",
model: "",
+ testStandardId: "",
unit: "",
quantity: "",
checkCompany: "",
@@ -132,6 +151,7 @@
checkName: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
productId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
model: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
+ testStandardId: [{required: true, message: "璇烽�夋嫨鎸囨爣", trigger: "change"}],
unit: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
checkCompany: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
@@ -169,6 +189,7 @@
const tableLoading = ref(false);
const userList = ref([]);
const currentProductId = ref(0);
+const testStandardOptions = ref([]); // 鎸囨爣閫夋嫨涓嬫媺妗嗘暟鎹�
// 鎵撳紑寮规
const openDialog = async (type, row) => {
@@ -180,11 +201,54 @@
let userLists = await userListNoPage();
userList.value = userLists.data;
form.value = {}
+ testStandardOptions.value = [];
+ tableData.value = [];
getProductOptions();
if (operationType.value === 'edit') {
- form.value = {...row}
+ // 鍏堜繚瀛� testStandardId锛岄伩鍏嶈娓呯┖
+ const savedTestStandardId = row.testStandardId;
+ // 鍏堣缃〃鍗曟暟鎹紝浣嗘殏鏃舵竻绌� testStandardId锛岀瓑閫夐」鍔犺浇瀹屾垚鍚庡啀璁剧疆
+ form.value = {...row, testStandardId: ''}
currentProductId.value = row.productId || 0
- getQualityInspectParamList(row.id)
+ // 缂栬緫妯″紡涓嬶紝鍏堝姞杞芥寚鏍囬�夐」锛岀劧鍚庡姞杞藉弬鏁板垪琛�
+ if (currentProductId.value) {
+ // 鍏堝姞杞芥寚鏍囬�夐」
+ let params = {
+ productId: currentProductId.value,
+ inspectType: 2
+ }
+ qualityInspectDetailByProductId(params).then(res => {
+ testStandardOptions.value = res.data || [];
+ // 浣跨敤 nextTick 鍜� setTimeout 纭繚閫夐」宸茬粡娓叉煋鍒� DOM
+ nextTick(() => {
+ setTimeout(() => {
+ // 濡傛灉缂栬緫鏁版嵁涓湁 testStandardId锛屽垯璁剧疆骞跺姞杞藉搴旂殑鍙傛暟
+ if (savedTestStandardId) {
+ // 纭繚绫诲瀷鍖归厤锛坕tem.id 鍙兘鏄暟瀛楁垨瀛楃涓诧級
+ const matchedOption = testStandardOptions.value.find(item =>
+ item.id == savedTestStandardId || String(item.id) === String(savedTestStandardId)
+ );
+ if (matchedOption) {
+ // 纭繚浣跨敤鍖归厤椤圭殑 id锛堜繚鎸佺被鍨嬩竴鑷达級
+ form.value.testStandardId = matchedOption.id;
+ console.log(22222,form.value.testStandardId);
+ handleTestStandardChange(matchedOption.id);
+ } else {
+ // 濡傛灉鎵句笉鍒板尮閰嶉」锛屽皾璇曠洿鎺ヤ娇鐢ㄥ師鍊�
+ console.warn('鏈壘鍒板尮閰嶇殑鎸囨爣閫夐」锛宼estStandardId:', savedTestStandardId, '鍙敤閫夐」:', testStandardOptions.value);
+ form.value.testStandardId = savedTestStandardId;
+ handleTestStandardChange(savedTestStandardId);
+ }
+ } else {
+ // 鍚﹀垯浣跨敤鏃х殑閫昏緫
+ getQualityInspectParamList(row.id);
+ }
+ }, 100);
+ });
+ });
+ } else {
+ getQualityInspectParamList(row.id);
+ }
}
}
const getProductOptions = () => {
@@ -195,7 +259,7 @@
const getModels = (value) => {
currentProductId.value = value
form.value.productName = findNodeById(productOptions.value, value);
- if (currentProductId) {
+ if (currentProductId.value) {
getList();
}
};
@@ -253,9 +317,40 @@
})
}
const getList = () => {
- qualityInspectDetailByProductId(currentProductId.value).then(res => {
- tableData.value = res.data;
+ if (!currentProductId.value) {
+ testStandardOptions.value = [];
+ tableData.value = [];
+ return;
+ }
+ let params = {
+ productId: currentProductId.value,
+ inspectType: 2
+ }
+ qualityInspectDetailByProductId(params).then(res => {
+ // 淇濆瓨涓嬫媺妗嗛�夐」鏁版嵁
+ testStandardOptions.value = res.data || [];
+ // 娓呯┖琛ㄦ牸鏁版嵁锛岀瓑寰呯敤鎴烽�夋嫨鎸囨爣
+ tableData.value = [];
+ // 娓呯┖鎸囨爣閫夋嫨
+ form.value.testStandardId = '';
})
+}
+
+// 鎸囨爣閫夋嫨鍙樺寲澶勭悊
+const handleTestStandardChange = (testStandardId) => {
+ if (!testStandardId) {
+ tableData.value = [];
+ return;
+ }
+ tableLoading.value = true;
+ getQualityTestStandardParamByTestStandardId(testStandardId).then(res => {
+ tableData.value = res.data || [];
+ }).catch(error => {
+ console.error('鑾峰彇鏍囧噯鍙傛暟澶辫触:', error);
+ tableData.value = [];
+ }).finally(() => {
+ tableLoading.value = false;
+ })
}
const getQualityInspectParamList = (id) => {
qualityInspectParamInfo(id).then(res => {
@@ -265,6 +360,9 @@
// 鍏抽棴寮规
const closeDia = () => {
proxy.resetForm("formRef");
+ tableData.value = [];
+ testStandardOptions.value = [];
+ form.value.testStandardId = '';
dialogFormVisible.value = false;
emit('close')
};
diff --git a/src/views/qualityManagement/finalInspection/components/inspectionFormDia.vue b/src/views/qualityManagement/finalInspection/components/inspectionFormDia.vue
index 32a36fa..411856c 100644
--- a/src/views/qualityManagement/finalInspection/components/inspectionFormDia.vue
+++ b/src/views/qualityManagement/finalInspection/components/inspectionFormDia.vue
@@ -34,7 +34,6 @@
<script setup>
import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
import {Search} from "@element-plus/icons-vue";
import {
qualityInspectParamDel,
diff --git a/src/views/qualityManagement/metricBinding/index.vue b/src/views/qualityManagement/metricBinding/index.vue
index d32a5df..ac67474 100644
--- a/src/views/qualityManagement/metricBinding/index.vue
+++ b/src/views/qualityManagement/metricBinding/index.vue
@@ -10,6 +10,7 @@
:isSelection="false"
:rowClassName="rowClassNameCenter"
:tableLoading="tableLoading"
+ :rowClick="handleTableRowClick"
@pagination="handlePagination"
:total="page.total"
>
@@ -197,12 +198,13 @@
}
const standardColumns = ref([
- { label: '鏍囧噯缂栧彿', prop: 'standardNo', dataType: 'slot', slot: 'standardNoCell', minWidth: 160, headerSlot: 'standardNoHeader' },
- { label: '鏍囧噯鍚嶇О', prop: 'standardName', minWidth: 180, headerSlot: 'standardNameHeader' },
+ { label: '鏍囧噯缂栧彿', prop: 'standardNo', dataType: 'slot', slot: 'standardNoCell', minWidth: 160, align: 'center', headerSlot: 'standardNoHeader' },
+ { label: '鏍囧噯鍚嶇О', prop: 'standardName', minWidth: 180, align: 'center', headerSlot: 'standardNameHeader' },
{
label: '绫诲埆',
prop: 'inspectType',
headerSlot: 'inspectTypeHeader',
+ align: 'center',
dataType: 'tag',
formatData: (val) => {
const map = { 0: '鍘熸潗鏂欐楠�', 1: '杩囩▼妫�楠�', 2: '鍑哄巶妫�楠�' }
@@ -212,6 +214,7 @@
{
label: '宸ュ簭',
prop: 'processId',
+ align: 'center',
dataType: 'tag',
formatData: (val) => {
const target = processOptions.value.find(
@@ -223,7 +226,8 @@
{
label: '澶囨敞',
prop: 'remark',
- minWidth: 160
+ minWidth: 160,
+ align: 'center'
}
// {
// label: '鐘舵��',
@@ -304,6 +308,13 @@
})
}
+// 琛ㄦ牸琛岀偣鍑伙紝鍔犺浇鍙充晶缁戝畾鍒楄〃
+const handleTableRowClick = (row) => {
+ currentStandard.value = row
+ loadBindingList()
+}
+
+// 宸︿晶琛岀偣鍑伙紝鍔犺浇鍙充晶缁戝畾鍒楄〃锛堜繚鐣欑敤浜庢爣鍑嗙紪鍙峰垪鐨勭偣鍑伙級
const handleStandardRowClick = (row) => {
currentStandard.value = row
loadBindingList()
@@ -471,4 +482,23 @@
:deep(.center-table .el-table__body-wrapper td .cell) {
text-align: center !important;
}
+
+/* PIMTable 琛ㄥご灞呬腑 */
+:deep(.lims-table .pim-table-header-cell) {
+ text-align: center;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
+
+:deep(.lims-table .pim-table-header-title) {
+ text-align: center;
+ width: 100%;
+}
+
+:deep(.lims-table .pim-table-header-extra) {
+ width: 100%;
+ margin-top: 4px;
+}
</style>
diff --git a/src/views/qualityManagement/metricMaintenance/index.vue b/src/views/qualityManagement/metricMaintenance/index.vue
index f152a04..44d3fae 100644
--- a/src/views/qualityManagement/metricMaintenance/index.vue
+++ b/src/views/qualityManagement/metricMaintenance/index.vue
@@ -19,6 +19,7 @@
:isSelection="true"
:tableLoading="tableLoading"
:rowClassName="rowClassNameCenter"
+ :rowClick="handleTableRowClick"
@selection-change="handleSelectionChange"
@pagination="handlePagination"
:total="page.total"
@@ -212,7 +213,7 @@
standardNo: [{ required: true, message: '璇疯緭鍏ユ爣鍑嗙紪鍙�', trigger: 'blur' }],
standardName: [{ required: true, message: '璇疯緭鍏ユ爣鍑嗗悕绉�', trigger: 'blur' }],
inspectType: [{ required: true, message: '璇烽�夋嫨妫�娴嬬被鍨�', trigger: 'change' }],
- processId: [{ required: true, message: '璇烽�夋嫨宸ュ簭', trigger: 'change' }]
+ processId: [{ required: false, message: '璇烽�夋嫨宸ュ簭', trigger: 'change' }]
}
})
@@ -277,18 +278,21 @@
dataType: 'slot',
slot: 'standardNoCell',
minWidth: 160,
+ align: 'center',
headerSlot: 'standardNoHeader'
},
{
label: '鏍囧噯鍚嶇О',
prop: 'standardName',
minWidth: 180,
+ align: 'center',
headerSlot: 'standardNameHeader'
},
{
label: '绫诲埆',
prop: 'inspectType',
headerSlot: 'inspectTypeHeader',
+ align: 'center',
dataType: 'tag',
formatData: (val) => {
const map = {
@@ -302,6 +306,7 @@
{
label: '宸ュ簭',
prop: 'processId',
+ align: 'center',
dataType: 'tag',
formatData: (val) => {
const target = processOptions.value.find(
@@ -314,6 +319,7 @@
label: '鐘舵��',
prop: 'state',
headerSlot: 'stateHeader',
+ align: 'center',
dataType: 'tag',
formatData: (val) => {
const map = {
@@ -332,7 +338,8 @@
{
label: '澶囨敞',
prop: 'remark',
- minWidth: 160
+ minWidth: 160,
+ align: 'center'
},
{
dataType: 'action',
@@ -447,7 +454,13 @@
getStandardList()
}
-// 宸︿晶琛岀偣鍑伙紝鍔犺浇鍙充晶鍙傛暟
+// 琛ㄦ牸琛岀偣鍑伙紝鍔犺浇鍙充晶鍙傛暟
+const handleTableRowClick = (row) => {
+ currentStandard.value = row
+ loadDetail(row.id)
+}
+
+// 宸︿晶琛岀偣鍑伙紝鍔犺浇鍙充晶鍙傛暟锛堜繚鐣欑敤浜庢爣鍑嗙紪鍙峰垪鐨勭偣鍑伙級
const handleStandardRowClick = (row) => {
currentStandard.value = row
loadDetail(row.id)
@@ -567,14 +580,23 @@
processId: ''
})
} else if (type === 'edit' && row) {
- Object.assign(standardForm.value, row)
+ Object.assign(standardForm.value, {
+ ...row,
+ // 纭繚 inspectType 鍜� state 杞崲涓哄瓧绗︿覆锛屼互鍖归厤 el-select 鐨� value 绫诲瀷
+ inspectType: row.inspectType !== null && row.inspectType !== undefined ? String(row.inspectType) : '',
+ state: row.state !== null && row.state !== undefined ? String(row.state) : '0',
+ // 纭繚 processId 杞崲涓哄瓧绗︿覆鎴栨暟瀛楋紙鏍规嵁瀹為檯闇�瑕侊級
+ processId: row.processId !== null && row.processId !== undefined ? row.processId : ''
+ })
} else if (type === 'copy' && row) {
const { id, ...rest } = row
Object.assign(standardForm.value, {
...rest,
id: undefined,
standardNo: '',
- state: '0'
+ state: '0',
+ // 纭繚 inspectType 杞崲涓哄瓧绗︿覆
+ inspectType: rest.inspectType !== null && rest.inspectType !== undefined ? String(rest.inspectType) : ''
})
}
standardDialogVisible.value = true
@@ -673,14 +695,41 @@
.metric-maintenance {
display: flex;
gap: 16px;
+ min-width: 0; /* 鍏佽 flex 瀛愬厓绱犳敹缂� */
}
.left-panel,
.right-panel {
flex: 1;
+ min-width: 0; /* 鍏佽 flex 瀛愬厓绱犳敹缂� */
background: #ffffff;
padding: 16px;
box-sizing: border-box;
+ overflow: hidden; /* 闃叉鍐呭婧㈠嚭 */
+}
+
+/* 浣庡垎杈ㄧ巼閫傞厤 */
+@media (max-width: 1400px) {
+ .metric-maintenance {
+ flex-direction: column;
+ }
+
+ .left-panel,
+ .right-panel {
+ width: 100%;
+ min-width: 0;
+ }
+}
+
+@media (max-width: 768px) {
+ .metric-maintenance {
+ gap: 12px;
+ }
+
+ .left-panel,
+ .right-panel {
+ padding: 12px;
+ }
}
.toolbar {
@@ -688,6 +737,8 @@
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
+ flex-wrap: wrap;
+ gap: 8px;
}
.toolbar-left {
@@ -699,6 +750,9 @@
.toolbar-right {
flex-shrink: 0;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
}
.search-label {
@@ -758,4 +812,23 @@
:deep(.center-table .el-table__body-wrapper td .cell) {
text-align: center !important;
}
+
+/* PIMTable 琛ㄥご灞呬腑 */
+:deep(.lims-table .pim-table-header-cell) {
+ text-align: center;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
+
+:deep(.lims-table .pim-table-header-title) {
+ text-align: center;
+ width: 100%;
+}
+
+:deep(.lims-table .pim-table-header-extra) {
+ width: 100%;
+ margin-top: 4px;
+}
</style>
\ No newline at end of file
diff --git a/src/views/qualityManagement/processInspection/components/formDia.vue b/src/views/qualityManagement/processInspection/components/formDia.vue
index 6126e6b..4821db2 100644
--- a/src/views/qualityManagement/processInspection/components/formDia.vue
+++ b/src/views/qualityManagement/processInspection/components/formDia.vue
@@ -9,8 +9,21 @@
<el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
<el-row :gutter="30">
<el-col :span="12">
- <el-form-item label="宸ュ簭锛�" prop="process">
- <el-input v-model="form.process" placeholder="璇疯緭鍏�" clearable/>
+ <el-form-item label="宸ュ簭锛�" prop="processId">
+ <el-select
+ v-model="form.processId"
+ placeholder="璇烽�夋嫨宸ュ簭"
+ clearable
+ @change="handleProcessChange"
+ style="width: 100%"
+ >
+ <el-option
+ v-for="item in processOptions"
+ :key="item.value"
+ :label="item.label"
+ :value="item.value"
+ />
+ </el-select>
</el-form-item>
</el-col>
<el-col :span="12">
@@ -32,6 +45,24 @@
<el-col :span="12">
<el-form-item label="瑙勬牸鍨嬪彿锛�" prop="model">
<el-input v-model="form.model" placeholder="璇疯緭鍏�" clearable/>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鎸囨爣閫夋嫨锛�" prop="testStandardId">
+ <el-select
+ v-model="form.testStandardId"
+ placeholder="璇烽�夋嫨鎸囨爣"
+ clearable
+ @change="handleTestStandardChange"
+ style="width: 100%"
+ >
+ <el-option
+ v-for="item in testStandardOptions"
+ :key="item.id"
+ :label="item.standardName || item.standardNo"
+ :value="item.id"
+ />
+ </el-select>
</el-form-item>
</el-col>
</el-row>
@@ -108,11 +139,12 @@
</template>
<script setup>
-import {ref} from "vue";
+import {ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue";
import {getOptions} from "@/api/procurementManagement/procurementLedger.js";
import {productTreeList} from "@/api/basicData/product.js";
+import {productProcessListPage} from "@/api/basicData/productProcess.js";
import {qualityInspectAdd, qualityInspectUpdate} from "@/api/qualityManagement/rawMaterialInspection.js";
-import {qualityInspectDetailByProductId} from "@/api/qualityManagement/metricMaintenance.js";
+import {qualityInspectDetailByProductId, getQualityTestStandardParamByTestStandardId} from "@/api/qualityManagement/metricMaintenance.js";
import {userListNoPage} from "@/api/system/user.js";
import {qualityInspectParamInfo} from "@/api/qualityManagement/qualityInspectParam.js";
const { proxy } = getCurrentInstance()
@@ -123,11 +155,12 @@
const data = reactive({
form: {
checkTime: "",
- process: "",
+ processId: "",
checkName: "",
productName: "",
productId: "",
model: "",
+ testStandardId: "",
unit: "",
quantity: "",
checkCompany: "",
@@ -135,10 +168,11 @@
},
rules: {
checkTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
- process: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ processId: [{ required: true, message: "璇烽�夋嫨宸ュ簭", trigger: "change" }],
checkName: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
productId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
model: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
+ testStandardId: [{required: true, message: "璇烽�夋嫨鎸囨爣", trigger: "change"}],
unit: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
checkCompany: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
@@ -176,6 +210,24 @@
const tableData = ref([]);
const tableLoading = ref(false);
const currentProductId = ref(0);
+const processOptions = ref([]); // 宸ュ簭涓嬫媺妗嗘暟鎹�
+const testStandardOptions = ref([]); // 鎸囨爣閫夋嫨涓嬫媺妗嗘暟鎹�
+
+// 鑾峰彇宸ュ簭鍒楄〃
+const getProcessList = async () => {
+ try {
+ const res = await productProcessListPage({ current: 1, size: 1000 })
+ if (res?.code === 200) {
+ const records = res?.data?.records || []
+ processOptions.value = records.map(item => ({
+ label: item.processName || item.name || item.label,
+ value: item.id || item.processId || item.value
+ }))
+ }
+ } catch (error) {
+ console.error('鑾峰彇宸ュ簭鍒楄〃澶辫触:', error)
+ }
+}
// 鎵撳紑寮规
const openDialog = async (type, row) => {
@@ -187,11 +239,64 @@
let userLists = await userListNoPage();
userList.value = userLists.data;
form.value = {}
+ testStandardOptions.value = [];
+ tableData.value = [];
getProductOptions();
+ // 鍏堝姞杞藉伐搴忓垪琛�
+ await getProcessList();
if (operationType.value === 'edit') {
- form.value = {...row}
+ // 鍏堜繚瀛� testStandardId锛岄伩鍏嶈娓呯┖
+ const savedTestStandardId = row.testStandardId;
+ // 鍏堣缃〃鍗曟暟鎹紝浣嗘殏鏃舵竻绌� testStandardId锛岀瓑閫夐」鍔犺浇瀹屾垚鍚庡啀璁剧疆
+ form.value = {...row, testStandardId: ''}
+ // 鍏煎鏃ф暟鎹細濡傛灉 row 涓湁 process 瀛楁锛岃浆鎹负 processId
+ if (row.process && !row.processId) {
+ // 灏濊瘯浠� processOptions 涓煡鎵惧尮閰嶇殑宸ュ簭
+ const processOption = processOptions.value.find(p => p.label === row.process);
+ if (processOption) {
+ form.value.processId = processOption.value;
+ }
+ }
currentProductId.value = row.productId || 0
- getQualityInspectParamList(row.id)
+ // 缂栬緫妯″紡涓嬶紝鍏堝姞杞芥寚鏍囬�夐」锛岀劧鍚庡姞杞藉弬鏁板垪琛�
+ if (currentProductId.value) {
+ // 鍏堝姞杞芥寚鏍囬�夐」
+ let params = {
+ productId: currentProductId.value,
+ inspectType: 1,
+ process: form.value.processId ? processOptions.value.find(p => p.value === form.value.processId)?.label : ''
+ }
+ qualityInspectDetailByProductId(params).then(res => {
+ testStandardOptions.value = res.data || [];
+ // 浣跨敤 nextTick 鍜� setTimeout 纭繚閫夐」宸茬粡娓叉煋鍒� DOM
+ nextTick(() => {
+ setTimeout(() => {
+ // 濡傛灉缂栬緫鏁版嵁涓湁 testStandardId锛屽垯璁剧疆骞跺姞杞藉搴旂殑鍙傛暟
+ if (savedTestStandardId) {
+ // 纭繚绫诲瀷鍖归厤锛坕tem.id 鍙兘鏄暟瀛楁垨瀛楃涓诧級
+ const matchedOption = testStandardOptions.value.find(item =>
+ item.id == savedTestStandardId || String(item.id) === String(savedTestStandardId)
+ );
+ if (matchedOption) {
+ // 纭繚浣跨敤鍖归厤椤圭殑 id锛堜繚鎸佺被鍨嬩竴鑷达級
+ form.value.testStandardId = matchedOption.id;
+ handleTestStandardChange(matchedOption.id);
+ } else {
+ // 濡傛灉鎵句笉鍒板尮閰嶉」锛屽皾璇曠洿鎺ヤ娇鐢ㄥ師鍊�
+ console.warn('鏈壘鍒板尮閰嶇殑鎸囨爣閫夐」锛宼estStandardId:', savedTestStandardId, '鍙敤閫夐」:', testStandardOptions.value);
+ form.value.testStandardId = savedTestStandardId;
+ handleTestStandardChange(savedTestStandardId);
+ }
+ } else {
+ // 鍚﹀垯浣跨敤鏃х殑閫昏緫
+ getQualityInspectParamList(row.id);
+ }
+ }, 100);
+ });
+ });
+ } else {
+ getQualityInspectParamList(row.id);
+ }
}
}
const getProductOptions = () => {
@@ -202,7 +307,7 @@
const getModels = (value) => {
currentProductId.value = value
form.value.productName = findNodeById(productOptions.value, value);
- if (currentProductId) {
+ if (currentProductId.value) {
getList();
}
};
@@ -234,17 +339,31 @@
return newItem;
});
}
+// 宸ュ簭鍙樺寲澶勭悊
+const handleProcessChange = () => {
+ // 宸ュ簭鍙樺寲鏃讹紝濡傛灉宸查�夋嫨浜у搧锛岄噸鏂板姞杞芥寚鏍囧垪琛�
+ if (currentProductId.value) {
+ getList();
+ }
+}
+
// 鎻愪氦浜у搧琛ㄥ崟
const submitForm = () => {
proxy.$refs.formRef.validate(valid => {
if (valid) {
form.value.inspectType = 1
+ // 灏� processId 杞崲涓� process 鍚嶇О锛堝鏋滃悗绔渶瑕� process 瀛楁锛�
+ const processName = form.value.processId ? processOptions.value.find(p => p.value === form.value.processId)?.label : '';
if (operationType.value === "add") {
tableData.value.forEach((item) => {
delete item.id
})
}
- const data = {...form.value, qualityInspectParams: tableData.value}
+ const data = {
+ ...form.value,
+ process: processName, // 淇濈暀 process 瀛楁浠ュ吋瀹瑰悗绔�
+ qualityInspectParams: tableData.value
+ }
if (operationType.value === "add") {
qualityInspectAdd(data).then(res => {
proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
@@ -260,8 +379,42 @@
})
}
const getList = () => {
- qualityInspectDetailByProductId(currentProductId.value).then(res => {
- tableData.value = res.data;
+ if (!currentProductId.value) {
+ testStandardOptions.value = [];
+ tableData.value = [];
+ return;
+ }
+ // 鑾峰彇宸ュ簭鍚嶇О
+ const processName = form.value.processId ? processOptions.value.find(p => p.value === form.value.processId)?.label : '';
+ let params = {
+ productId: currentProductId.value,
+ inspectType: 1,
+ process: processName
+ }
+ qualityInspectDetailByProductId(params).then(res => {
+ // 淇濆瓨涓嬫媺妗嗛�夐」鏁版嵁
+ testStandardOptions.value = res.data || [];
+ // 娓呯┖琛ㄦ牸鏁版嵁锛岀瓑寰呯敤鎴烽�夋嫨鎸囨爣
+ tableData.value = [];
+ // 娓呯┖鎸囨爣閫夋嫨
+ form.value.testStandardId = '';
+ })
+}
+
+// 鎸囨爣閫夋嫨鍙樺寲澶勭悊
+const handleTestStandardChange = (testStandardId) => {
+ if (!testStandardId) {
+ tableData.value = [];
+ return;
+ }
+ tableLoading.value = true;
+ getQualityTestStandardParamByTestStandardId(testStandardId).then(res => {
+ tableData.value = res.data || [];
+ }).catch(error => {
+ console.error('鑾峰彇鏍囧噯鍙傛暟澶辫触:', error);
+ tableData.value = [];
+ }).finally(() => {
+ tableLoading.value = false;
})
}
const getQualityInspectParamList = (id) => {
@@ -272,6 +425,9 @@
// 鍏抽棴寮规
const closeDia = () => {
proxy.resetForm("formRef");
+ tableData.value = [];
+ testStandardOptions.value = [];
+ form.value.testStandardId = '';
dialogFormVisible.value = false;
emit('close')
};
diff --git a/src/views/qualityManagement/processInspection/components/inspectionFormDia.vue b/src/views/qualityManagement/processInspection/components/inspectionFormDia.vue
index 32a36fa..411856c 100644
--- a/src/views/qualityManagement/processInspection/components/inspectionFormDia.vue
+++ b/src/views/qualityManagement/processInspection/components/inspectionFormDia.vue
@@ -34,7 +34,6 @@
<script setup>
import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
import {Search} from "@element-plus/icons-vue";
import {
qualityInspectParamDel,
diff --git a/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue b/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
index 5ea1e47..5cafd2c 100644
--- a/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
+++ b/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
@@ -45,6 +45,24 @@
<el-input v-model="form.model" placeholder="璇疯緭鍏�" clearable/>
</el-form-item>
</el-col>
+ <el-col :span="12">
+ <el-form-item label="鎸囨爣閫夋嫨锛�" prop="testStandardId">
+ <el-select
+ v-model="form.testStandardId"
+ placeholder="璇烽�夋嫨鎸囨爣"
+ clearable
+ @change="handleTestStandardChange"
+ style="width: 100%"
+ >
+ <el-option
+ v-for="item in testStandardOptions"
+ :key="item.id"
+ :label="item.standardName || item.standardNo"
+ :value="item.id"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
@@ -121,13 +139,13 @@
</template>
<script setup>
-import {ref} from "vue";
+import {ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue";
import {getOptions} from "@/api/procurementManagement/procurementLedger.js";
import {productTreeList} from "@/api/basicData/product.js";
import {qualityInspectAdd, qualityInspectUpdate} from "@/api/qualityManagement/rawMaterialInspection.js";
import {ElMessageBox} from "element-plus";
import {qualityInspectParamDel, qualityInspectParamInfo} from "@/api/qualityManagement/qualityInspectParam.js";
-import {qualityInspectDetailByProductId} from "@/api/qualityManagement/metricMaintenance.js";
+import {qualityInspectDetailByProductId, getQualityTestStandardParamByTestStandardId} from "@/api/qualityManagement/metricMaintenance.js";
const {proxy} = getCurrentInstance()
const emit = defineEmits(['close'])
@@ -142,6 +160,7 @@
productName: "",
productId: "",
model: "",
+ testStandardId: "",
unit: "",
quantity: "",
checkCompany: "",
@@ -153,6 +172,7 @@
checkName: [{required: false, message: "璇疯緭鍏�", trigger: "blur"}],
productId: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
model: [{required: false, message: "璇疯緭鍏�", trigger: "blur"}],
+ testStandardId: [{required: true, message: "璇烽�夋嫨鎸囨爣", trigger: "change"}],
unit: [{required: false, message: "璇疯緭鍏�", trigger: "blur"}],
quantity: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
checkCompany: [{required: false, message: "璇疯緭鍏�", trigger: "blur"}],
@@ -190,6 +210,7 @@
const supplierList = ref([]);
const productOptions = ref([]);
const currentProductId = ref(0);
+const testStandardOptions = ref([]); // 鎸囨爣閫夋嫨涓嬫媺妗嗘暟鎹�
// 鎵撳紑寮规
const openDialog = (type, row) => {
@@ -199,11 +220,52 @@
supplierList.value = res.data;
});
form.value = {}
+ testStandardOptions.value = [];
+ tableData.value = [];
getProductOptions();
if (operationType.value === 'edit') {
+ // 鍏堜繚瀛� testStandardId锛岄伩鍏嶈娓呯┖
+ const savedTestStandardId = row.testStandardId;
form.value = {...row}
currentProductId.value = row.productId || 0
- getQualityInspectParamList(row.id)
+ // 缂栬緫妯″紡涓嬶紝鍏堝姞杞芥寚鏍囬�夐」锛岀劧鍚庡姞杞藉弬鏁板垪琛�
+ if (currentProductId.value) {
+ // 鍏堝姞杞芥寚鏍囬�夐」
+ let params = {
+ productId: currentProductId.value,
+ inspectType: 0
+ }
+ qualityInspectDetailByProductId(params).then(res => {
+ testStandardOptions.value = res.data || [];
+ // 浣跨敤 nextTick 鍜� setTimeout 纭繚閫夐」宸茬粡娓叉煋鍒� DOM
+ nextTick(() => {
+ setTimeout(() => {
+ // 濡傛灉缂栬緫鏁版嵁涓湁 testStandardId锛屽垯璁剧疆骞跺姞杞藉搴旂殑鍙傛暟
+ if (savedTestStandardId) {
+ // 纭繚绫诲瀷鍖归厤锛坕tem.id 鍙兘鏄暟瀛楁垨瀛楃涓诧級
+ const matchedOption = testStandardOptions.value.find(item =>
+ item.id == savedTestStandardId || String(item.id) === String(savedTestStandardId)
+ );
+ if (matchedOption) {
+ // 纭繚浣跨敤鍖归厤椤圭殑 id锛堜繚鎸佺被鍨嬩竴鑷达級
+ form.value.testStandardId = matchedOption.id;
+ handleTestStandardChange(matchedOption.id);
+ } else {
+ // 濡傛灉鎵句笉鍒板尮閰嶉」锛屽皾璇曠洿鎺ヤ娇鐢ㄥ師鍊�
+ console.warn('鏈壘鍒板尮閰嶇殑鎸囨爣閫夐」锛宼estStandardId:', savedTestStandardId, '鍙敤閫夐」:', testStandardOptions.value);
+ form.value.testStandardId = savedTestStandardId;
+ handleTestStandardChange(savedTestStandardId);
+ }
+ } else {
+ // 鍚﹀垯浣跨敤鏃х殑閫昏緫
+ getQualityInspectParamList(row.id);
+ }
+ }, 100);
+ });
+ });
+ } else {
+ getQualityInspectParamList(row.id);
+ }
}
}
const getProductOptions = () => {
@@ -214,7 +276,7 @@
const getModels = (value) => {
currentProductId.value = value
form.value.productName = findNodeById(productOptions.value, value);
- if (currentProductId) {
+ if (currentProductId.value) {
getList();
}
};
@@ -275,8 +337,39 @@
}
const getList = () => {
- qualityInspectDetailByProductId(currentProductId.value).then(res => {
- tableData.value = res.data;
+ if (!currentProductId.value) {
+ testStandardOptions.value = [];
+ tableData.value = [];
+ return;
+ }
+ let params = {
+ productId: currentProductId.value,
+ inspectType: 0
+ }
+ qualityInspectDetailByProductId(params).then(res => {
+ // 淇濆瓨涓嬫媺妗嗛�夐」鏁版嵁
+ testStandardOptions.value = res.data || [];
+ // 娓呯┖琛ㄦ牸鏁版嵁锛岀瓑寰呯敤鎴烽�夋嫨鎸囨爣
+ tableData.value = [];
+ // 娓呯┖鎸囨爣閫夋嫨
+ form.value.testStandardId = '';
+ })
+}
+
+// 鎸囨爣閫夋嫨鍙樺寲澶勭悊
+const handleTestStandardChange = (testStandardId) => {
+ if (!testStandardId) {
+ tableData.value = [];
+ return;
+ }
+ tableLoading.value = true;
+ getQualityTestStandardParamByTestStandardId(testStandardId).then(res => {
+ tableData.value = res.data || [];
+ }).catch(error => {
+ console.error('鑾峰彇鏍囧噯鍙傛暟澶辫触:', error);
+ tableData.value = [];
+ }).finally(() => {
+ tableLoading.value = false;
})
}
@@ -288,7 +381,9 @@
// 鍏抽棴寮规
const closeDia = () => {
proxy.resetForm("formRef");
- tableData.value = []
+ tableData.value = [];
+ testStandardOptions.value = [];
+ form.value.testStandardId = '';
dialogFormVisible.value = false;
emit('close')
};
diff --git a/src/views/qualityManagement/rawMaterialInspection/components/inspectionFormDia.vue b/src/views/qualityManagement/rawMaterialInspection/components/inspectionFormDia.vue
index 32a36fa..411856c 100644
--- a/src/views/qualityManagement/rawMaterialInspection/components/inspectionFormDia.vue
+++ b/src/views/qualityManagement/rawMaterialInspection/components/inspectionFormDia.vue
@@ -34,7 +34,6 @@
<script setup>
import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
import {Search} from "@element-plus/icons-vue";
import {
qualityInspectParamDel,
diff --git a/src/views/reportAnalysis/dataDashboard/index.vue b/src/views/reportAnalysis/dataDashboard/index.vue
index 574c3f2..566d7ea 100644
--- a/src/views/reportAnalysis/dataDashboard/index.vue
+++ b/src/views/reportAnalysis/dataDashboard/index.vue
@@ -22,34 +22,44 @@
<div class="left-panel">
<!-- 瀹㈡埛淇℃伅缁熻鍒嗘瀽 -->
<div class="panel-header">
- <span class="panel-title">瀹㈡埛淇℃伅缁熻鍒嗘瀽</span>
+ <span class="panel-title">鍦ㄥ埗鍝佺粺璁″垎鏋�</span>
</div>
<div class="panel-item-customers">
- <div class="panel-title-second">
- <div class="panel-title-icon"></div>
- <div class="total-customers">
- <span class="label">鎬诲悎鍚岄噾棰�(鍏�)</span>
- <span class="value">{{sum}}</span>
+ <div class="quality-cards">
+ <div class="quality-cardSec">
+ <div class="quality-card one"></div>
+ <div class="quality-cardTitle">
+ <div>鎬诲湪鍒舵暟閲�</div>
+ <div>{{workInProcessStatistics.totalQuantity}}浠�</div>
+ </div>
</div>
-<!-- <div class="jiantou"></div>-->
+ <div class="quality-cardSec">
+ <div class="quality-card two"></div>
+ <div class="quality-cardTitle">
+ <div>骞冲潎鍛ㄨ浆澶╂暟</div>
+ <div>{{workInProcessStatistics.avgTurnoverDays}}澶�</div>
+ </div>
+ </div>
+ <div class="quality-cardSec">
+ <div class="quality-card three"></div>
+ <div class="quality-cardTitle">
+ <div>鍛ㄨ浆鏁堢巼</div>
+ <div>{{workInProcessStatistics.turnoverEfficiency}}%</div>
+ </div>
+ </div>
</div>
- <!-- 楗煎浘鍖哄煙 -->
- <div style="display: flex;align-items: center;gap: 20px;justify-content: space-evenly;height: 82%;margin-top: 20px">
- <div style="width: 240px; height: 240px; background-image: url('/src/assets/BI/zonghetongbingtubiankuang@2x.png'); background-size: contain; background-position: center; background-repeat: no-repeat; display: flex; align-items: center; justify-content: center;">
- <Echarts ref="chart" :legend="pieLegend" :chartStyle="chartStylePie"
- :series="materialPieSeries"
- :tooltip="pieTooltip"
- :options="{backgroundColor: 'transparent'}"
- style="margin-left: 5px;"></Echarts>
- </div>
- <ul class="contract-list" style="margin: 0; padding: 0; display: flex; flex-direction: column;justify-content: space-around; height: 100%; overflow-y: auto; scroll-behavior: smooth;" ref="refContractList">
- <li v-for="item in materialPieSeries[0].data" :key="item.name" style="list-style: none; margin-bottom: 12px;">
- <div style="display: flex;align-items: center;justify-content: space-between;width: 100%">
- <div class="line" :style="{color: item.itemStyle.color}">鈻� {{item.name}}</div>
- <div style="font-weight: 700;font-size: 16px;color: #85B1E4;">锟{item.value}}</div>
- </div>
- </li>
- </ul>
+ <!-- 宸ュ簭鍦ㄥ埗鍝佹暟閲忔煴鐘跺浘 -->
+ <div style="height: 82%;margin-top: 20px">
+ <Echarts ref="chart"
+ :chartStyle="chartStyle"
+ :grid="grid"
+ :legend="workInProcessBarLegend"
+ :series="workInProcessBarSeries"
+ :tooltip="tooltip"
+ :xAxis="workInProcessXAxis"
+ :yAxis="workInProcessYAxis"
+ :options="{backgroundColor: 'transparent', textStyle: {color: '#B8C8E0'}}"
+ style="height: 100%"></Echarts>
</div>
</div>
@@ -63,21 +73,21 @@
<div class="quality-cardSec">
<div class="quality-card one"></div>
<div class="quality-cardTitle">
- <div>鍘熸潗鏂欏凡妫�娴嬫暟</div>
+ <div>鍘熸潗鏂欐鏁�</div>
<div>{{qualityStatisticsObject.supplierNum}}浠�</div>
</div>
</div>
<div class="quality-cardSec">
<div class="quality-card two"></div>
<div class="quality-cardTitle">
- <div>杩囩▼妫�楠屾暟閲�</div>
+ <div>杩囩▼妫�鏁�</div>
<div>{{qualityStatisticsObject.processNum}}浠�</div>
</div>
</div>
<div class="quality-cardSec">
<div class="quality-card three"></div>
<div class="quality-cardTitle">
- <div>鍑哄巶宸叉鏁伴噺</div>
+ <div>鍑哄巶妫�鏁�</div>
<div>{{qualityStatisticsObject.factoryNum}}浠�</div>
</div>
</div>
@@ -179,20 +189,72 @@
</div>
<div class="main-panel">
<div class="panel-item-customers">
- <div class="event-header">
- <img src="@/assets/BI/shijianmingxiicon@2x.png" alt="鍥炬爣" class="event-icon" />
- <span class="event-title">缁忚惀鍒嗘瀽</span>
+ <div class="order-statistics-cards" style="margin-bottom: 0px;">
+ <div class="quality-cardSec">
+ <div class="quality-card four"></div>
+ <div class="quality-cardTitle">
+ <div>鎬昏鍗曟暟</div>
+ <div>{{orderStatisticsObject.totalOrderCount}}浠�</div>
+ </div>
+ </div>
+ <div class="quality-cardSec">
+ <div class="quality-card five"></div>
+ <div class="quality-cardTitle">
+ <div>鏈畬鎴愯鍗曟暟</div>
+ <div>{{orderStatisticsObject.uncompletedOrderCount}}浠�</div>
+ </div>
+ </div>
+ <div class="quality-cardSec">
+ <div class="quality-card six"></div>
+ <div class="quality-cardTitle">
+ <div>閮ㄥ垎瀹屾垚璁㈠崟鏁�</div>
+ <div>{{orderStatisticsObject.partialCompletedOrderCount}}浠�</div>
+ </div>
+ </div>
+ <div class="quality-cardSec">
+ <div class="quality-card seven"></div>
+ <div class="quality-cardTitle">
+ <div>宸插畬鎴愯鍗曟暟</div>
+ <div>{{orderStatisticsObject.completedOrderCount}}浠�</div>
+ </div>
+ </div>
</div>
- <Echarts ref="chart"
- :chartStyle="chartStyle"
- :grid="grid"
- :legend="barLegend1"
- :series="barSeries11"
- :tooltip="tooltip"
- :xAxis="xAxis3"
- :yAxis="yAxis3"
- :options="{backgroundColor: 'transparent', textStyle: {color: '#B8C8E0'}}"
- style="height: 170px"></Echarts>
+ <div class="progress-table-container" ref="progressTableRef" style="margin-top: 0px;" @scroll="handleTableScroll">
+ <table class="progress-table">
+ <thead>
+ <tr>
+ <th>鐢熶骇璁㈠崟鍙�</th>
+ <th>浜у搧鍚嶇О</th>
+ <th>瑙勬牸</th>
+ <th>闇�姹傛暟閲�</th>
+ <th>瀹屾垚鏁伴噺</th>
+ <th>瀹屾垚杩涘害</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr
+ v-for="(item, index) in progressTableData"
+ :key="index"
+ :ref="el => setRowRef(el, index)"
+ :class="{ 'row-under-header': isRowUnderHeader(index) }"
+ >
+ <td>{{ item.npsNo || '-' }}</td>
+ <td>{{ item.productCategory || '-' }}</td>
+ <td>{{ item.specificationModel || '-' }}</td>
+ <td>{{ item.quantity || 0 }}</td>
+ <td>{{ item.completeQuantity || 0 }}</td>
+ <td>
+ <el-progress
+ :percentage="calculateProgress(item)"
+ :color="progressColor(calculateProgress(item))"
+ :status="calculateProgress(item) >= 100 ? 'success' : ''"
+ :stroke-width="8"
+ />
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
</div>
</div>
</div>
@@ -253,7 +315,7 @@
getProgressStatistics,
getWorkInProcessTurnover
} from "@/api/viewIndex.js";
-import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
+import {staffOnJobListPage} from "@/api/personnelManagement/employeeRecord.js";
import {listCustomer} from "@/api/basicData/customerFile.js";
import {listSupplier} from "@/api/basicData/supplierManageFile.js";
import {getLedgerPage} from "@/api/equipmentManagement/ledger.js";
@@ -261,6 +323,7 @@
import {getUpkeepPage} from "@/api/equipmentManagement/upkeep.js";
import {measuringInstrumentListPage} from "@/api/equipmentManagement/measurementEquipment.js";
import {listPageAnalysis} from "@/api/financialManagement/expenseManagement.js";
+import {productOrderListPage} from "@/api/productionManagement/productionOrder.js";
// 鍏ㄥ睆鐩稿叧鐘舵��
const isFullscreen = ref(false);
@@ -288,11 +351,17 @@
const realtimeLineChartRef = ref(null)
const refContractList = ref(null)
const refTodoList = ref(null)
+const progressTableRef = ref(null)
const timerScroll = ref(null)
+const progressTableScrollTimer = ref(null)
+const isTableScrolling = ref(false)
+const tableScrollTimeout = ref(null)
+const tableRowRefs = ref([])
+const rowsUnderHeader = ref(new Set())
const chartStylePie = {
- width: '140%',
- height: '140%' // 璁剧疆鍥捐〃瀹瑰櫒鐨勯珮搴�
+ width: '100%',
+ height: '100%' // 璁剧疆鍥捐〃瀹瑰櫒鐨勯珮搴�
}
const materialPieSeries = ref([
{
@@ -336,6 +405,21 @@
supplierNum: 0,
processNum: 0,
factoryNum: 0,
+})
+
+// 璁㈠崟缁熻瀵硅薄
+const orderStatisticsObject = ref({
+ totalOrderCount: 0,
+ uncompletedOrderCount: 0,
+ partialCompletedOrderCount: 0,
+ completedOrderCount: 0,
+})
+
+// 鍦ㄥ埗鍝佸懆杞粺璁″璞�
+const workInProcessStatistics = ref({
+ totalQuantity: 0,
+ avgTurnoverDays: 0,
+ turnoverEfficiency: 0,
})
const chartStyle = {
width: '100%',
@@ -579,8 +663,83 @@
axisLabel: { color: '#B8C8E0' }
}]
+// 鍦ㄥ埗鍝佸伐搴忔煴鐘跺浘閰嶇疆
+const workInProcessXAxis = ref([{
+ type: 'category',
+ axisTick: { show: false },
+ axisLabel: { color: '#B8C8E0' },
+ data: []
+}])
+const workInProcessYAxis = [{
+ type: 'value',
+ axisLabel: { color: '#B8C8E0' },
+ name: ''
+}]
+const workInProcessBarLegend = {
+ show: false,
+ textStyle: { color: '#B8C8E0' },
+ data: []
+}
+const workInProcessBarSeries = ref([
+ {
+ name: '鍦ㄥ埗鍝佹暟閲�',
+ type: 'bar',
+ barWidth: 25, // 鍥哄畾鏌辩姸鍥惧搴︿负40px
+ barGap: 0,
+ emphasis: {
+ focus: 'series'
+ },
+ itemStyle: {
+ color: {
+ type: 'linear',
+ x: 0,
+ y: 0,
+ x2: 0,
+ y2: 1,
+ colorStops: [
+ { offset: 0, color: '#4EE4FF' },
+ { offset: 1, color: '#00A4ED' }
+ ]
+ }
+ },
+ label: {
+ show: true,
+ position: 'top',
+ color: '#B8C8E0'
+ },
+ data: []
+ }
+])
+
// 寰呭姙浜嬮」
const todoList = ref([])
+
+// 鐢熶骇璁㈠崟瀹屾垚杩涘害琛ㄦ牸鏁版嵁
+const progressTableData = ref([])
+
+// 璁$畻瀹屾垚杩涘害鐧惧垎姣�
+const calculateProgress = (item) => {
+ if (!item) return 0
+ // 浼樺厛浣跨敤completionStatus瀛楁
+ if (item.completionStatus !== undefined && item.completionStatus !== null) {
+ const percentage = Number(item.completionStatus)
+ if (isNaN(percentage)) return 0
+ return Math.min(Math.max(Math.round(percentage), 0), 100)
+ }
+ // 濡傛灉娌℃湁completionStatus锛屽垯鏍规嵁瀹屾垚鏁伴噺鍜岄渶姹傛暟閲忚绠�
+ if (!item.quantity || item.quantity === 0) return 0
+ const percentage = (item.completeQuantity || 0) / item.quantity * 100
+ return Math.min(Math.max(Math.round(percentage), 0), 100)
+}
+
+// 鏍规嵁杩涘害鐧惧垎姣旇繑鍥為鑹�
+const progressColor = (percentage) => {
+ const p = percentage || 0
+ if (p < 30) return "#f56c6c"
+ if (p < 50) return "#e6a23c"
+ if (p < 80) return "#409eff"
+ return "#67c23a"
+}
// 璁$畻缂╂斁姣斾緥
const calculateScale = () => {
@@ -635,6 +794,43 @@
}))
})
}
+// 鍦ㄥ埗鍝佸懆杞粺璁�
+const workInProcessTurnoverInfo = () => {
+ getWorkInProcessTurnover().then((res) => {
+ console.log("鍦ㄥ埗鍝佸懆杞粺璁℃暟鎹�:", res)
+
+ if (!res || !res.data) {
+ console.warn('鍦ㄥ埗鍝佸懆杞粺璁℃暟鎹负绌�')
+ return
+ }
+
+ // 浠庢帴鍙h幏鍙栫粺璁℃暟鎹�
+ workInProcessStatistics.value = {
+ totalQuantity: res.data.totalOrderCount || 0,
+ avgTurnoverDays: res.data.averageTurnoverDays || 0,
+ turnoverEfficiency: res.data.turnoverEfficiency || 0,
+ }
+
+ // 璁剧疆宸ュ簭鏌辩姸鍥炬暟鎹�
+ // X杞达細processDetails (宸ュ簭璇︽儏鏁扮粍)
+ // Y杞达細processQuantityDetails (宸ュ簭鏁伴噺璇︽儏鏁扮粍)
+ if (res.data.processDetails && Array.isArray(res.data.processDetails)) {
+ // 璁剧疆X杞存暟鎹紙宸ュ簭鍚嶇О锛�
+ workInProcessXAxis.value[0].data = res.data.processDetails
+ } else {
+ workInProcessXAxis.value[0].data = []
+ }
+
+ if (res.data.processQuantityDetails && Array.isArray(res.data.processQuantityDetails)) {
+ // 璁剧疆Y杞存暟鎹紙鍦ㄥ埗鍝佹暟閲忥級
+ workInProcessBarSeries.value[0].data = res.data.processQuantityDetails
+ } else {
+ workInProcessBarSeries.value[0].data = []
+ }
+ }).catch((error) => {
+ console.error('鑾峰彇鍦ㄥ埗鍝佸懆杞粺璁″け璐�:', error)
+ })
+}
// 璐ㄦ缁熻
const qualityStatisticsInfo = () => {
qualityStatistics().then((res) => {
@@ -651,6 +847,7 @@
}
// 鍚勭敓浜ц鍗曠殑瀹屾垚杩涘害缁熻
const progressStatisticsInfo = () => {
+ // 浠庣粺璁℃帴鍙h幏鍙栫粺璁℃暟鎹�
getProgressStatistics().then((res) => {
console.log("鐢熶骇璁㈠崟瀹屾垚杩涘害缁熻鏁版嵁:", res)
@@ -659,24 +856,22 @@
return
}
- // 璁剧疆X杞存暟鎹� - 浣跨敤鍒嗙被鍚嶇О
- xAxis3.value[0].data = ['宸插畬鎴愯繘搴︽暟', '鎬昏鍗曟暟', '鏈畬鎴愯鍗曟暟', '宸插畬鎴愯鍗曟暟']
-
- // 璁剧疆鍗曚釜绯诲垪鐨勬暟鎹� - 姣忎釜X杞村垎绫诲搴斾竴涓��
- if (barSeries11.value && barSeries11.value.length > 0) {
- barSeries11.value[0].data = [
- res.data.completedProgressCount || 0,
- res.data.totalOrderCount || 0,
- res.data.uncompletedOrderCount || 0,
- res.data.completedOrderCount || 0
- ]
+ // 浠庢帴鍙h幏鍙栫粺璁℃暟鎹�
+ orderStatisticsObject.value = {
+ totalOrderCount: res.data.totalOrderCount || 0,
+ uncompletedOrderCount: res.data.uncompletedOrderCount || 0,
+ partialCompletedOrderCount: res.data.partialCompletedOrderCount || 0,
+ completedOrderCount: res.data.completedOrderCount || 0
}
+ progressTableData.value = res.data.completedOrderDetails || []
+ // 閲嶇疆琛屽紩鐢�
+ tableRowRefs.value = []
+ rowsUnderHeader.value.clear()
- console.log('鍥捐〃鏁版嵁璁剧疆瀹屾垚:', {
- xAxis: xAxis3.value[0].data,
- series: barSeries11.value[0]?.data
+ // 鍦ㄨ幏鍙栧埌鏁版嵁鍚庯紝鍒濆鍖栨粴鍔ㄥ姛鑳�
+ nextTick(() => {
+ initProgressTableScroll()
})
-
}).catch((error) => {
console.error('鑾峰彇鐢熶骇璁㈠崟瀹屾垚杩涘害缁熻澶辫触:', error)
})
@@ -822,6 +1017,163 @@
// 鑷姩杞崲鍛ㄣ�佹湀銆佸搴︾殑瀹氭椂鍣�
const autoSwitchTimer = ref(null)
+
+// 璁剧疆琛屽紩鐢�
+const setRowRef = (el, index) => {
+ if (el) {
+ tableRowRefs.value[index] = el
+ }
+}
+
+// 鍒ゆ柇琛屾槸鍚﹀湪琛ㄥご涓嬫柟
+const isRowUnderHeader = (index) => {
+ return rowsUnderHeader.value.has(index)
+}
+
+// 澶勭悊琛ㄦ牸婊氬姩浜嬩欢
+const handleTableScroll = () => {
+ const tableContainer = progressTableRef.value
+ if (!tableContainer) return
+
+ const thead = tableContainer.querySelector('thead')
+ if (!thead) return
+
+ const theadHeight = thead.offsetHeight
+ const containerRect = tableContainer.getBoundingClientRect()
+ const containerTop = containerRect.top
+ const theadBottom = containerTop + theadHeight
+
+ // 娓呯┖涔嬪墠鐨勮褰�
+ rowsUnderHeader.value.clear()
+
+ // 妫�鏌ユ瘡涓�琛屾槸鍚﹀湪琛ㄥご涓嬫柟锛堣琛ㄥご閬尅锛�
+ tableRowRefs.value.forEach((row, index) => {
+ if (row) {
+ const rowRect = row.getBoundingClientRect()
+ const rowTop = rowRect.top
+ const rowBottom = rowRect.bottom
+
+ // 濡傛灉琛屼笌琛ㄥご鏈夐噸鍙狅紙琛屽湪琛ㄥご涓嬫柟琚伄鎸★級
+ // 琛岀殑椤堕儴鍦ㄨ〃澶村簳閮ㄤ笅鏂癸紝浣嗚鐨勫簳閮ㄥ湪琛ㄥご搴曢儴涓婃柟锛岃鏄庤閬尅
+ if (rowTop < theadBottom && rowBottom > containerTop) {
+ rowsUnderHeader.value.add(index)
+ }
+ }
+ })
+
+ // 娓呴櫎涔嬪墠鐨勫畾鏃跺櫒
+ if (tableScrollTimeout.value) {
+ clearTimeout(tableScrollTimeout.value)
+ }
+
+ // 婊氬姩鍋滄鍚庢竻绌烘贰鍖栨爣璁�
+ tableScrollTimeout.value = setTimeout(() => {
+ rowsUnderHeader.value.clear()
+ }, 150)
+}
+
+// 鍒濆鍖栫敓浜ц鍗曡繘搴﹁〃鏍兼粴鍔ㄥ姛鑳�
+const initProgressTableScroll = () => {
+ const tableContainer = progressTableRef.value
+ if (!tableContainer) return
+
+ // 娓呯悊涔嬪墠鐨勬粴鍔ㄥ姩鐢诲拰瀹氭椂鍣�
+ if (progressTableScrollTimer.value) {
+ cancelAnimationFrame(progressTableScrollTimer.value)
+ progressTableScrollTimer.value = null
+ }
+ if (tableContainer._pauseTimer) {
+ clearInterval(tableContainer._pauseTimer)
+ tableContainer._pauseTimer = null
+ }
+
+ const tbody = tableContainer.querySelector('tbody')
+ if (!tbody) return
+
+ // 娓呯悊涔嬪墠鍙兘瀛樺湪鐨勫厠闅嗚锛堜繚鐣欏師濮嬫暟鎹锛�
+ // 鍘熷鏁版嵁琛岀殑鏁伴噺搴旇绛変簬 progressTableData.value.length
+ const originalCount = progressTableData.value.length
+ const allRows = Array.from(tbody.querySelectorAll('tr'))
+ if (allRows.length > originalCount) {
+ // 绉婚櫎鎵�鏈夎秴杩囧師濮嬫暟閲忕殑琛岋紙杩欎簺鏄厠闅嗙殑琛岋級
+ for (let i = originalCount; i < allRows.length; i++) {
+ allRows[i].remove()
+ }
+ }
+
+ const scrollItems = Array.from(tbody.querySelectorAll('tr'))
+ if (scrollItems.length === 0) return
+
+ // 鑾峰彇鍘熷鏁版嵁椤规暟閲�
+ const originalItemCount = scrollItems.length
+
+ // 璁$畻瀹瑰櫒楂樺害鍜岃〃澶撮珮搴�
+ const thead = tableContainer.querySelector('thead')
+ const theadHeight = thead ? thead.offsetHeight : 40
+ const containerHeight = tableContainer.clientHeight
+ const visibleHeight = containerHeight - theadHeight
+
+ // 璁$畻鍘熷鏁版嵁鐨勬�婚珮搴�
+ const itemHeight = scrollItems[0]?.offsetHeight || 40
+ const totalContentHeight = itemHeight * originalItemCount
+
+ // 濡傛灉鏁版嵁閲忎笉澶燂紝瀹瑰櫒鍙互瀹屽叏鏄剧ず鎵�鏈夋暟鎹紝灏变笉闇�瑕佹粴鍔ㄥ拰鍏嬮殕
+ if (totalContentHeight <= visibleHeight) {
+ // 鏁版嵁閲忓皯锛屼笉闇�瑕佹粴鍔紝鐩存帴杩斿洖
+ return
+ }
+
+ // 鏁版嵁閲忚冻澶燂紝闇�瑕佹粴鍔紝杩涜鍏嬮殕浠ュ疄鐜版棤缂濇粴鍔�
+ const cloneCount = Math.ceil(visibleHeight / itemHeight) + 2
+
+ // 鍏嬮殕鍓嶅嚑涓」鐩苟娣诲姞鍒板垪琛ㄦ湯灏撅紝瀹炵幇鏃犵紳婊氬姩
+ for (let i = 0; i < cloneCount; i++) {
+ const clone = scrollItems[i % originalItemCount].cloneNode(true)
+ tbody.appendChild(clone)
+ }
+
+ let scrollPosition = 0
+ const scrollSpeed = 1.5
+ const pauseTime = 3000
+ let isPaused = false
+ let lastTimestamp = 0
+
+ // 杩炵画婊氬姩鍔ㄧ敾鍑芥暟
+ function scrollAnimation(timestamp) {
+ if (!lastTimestamp) lastTimestamp = timestamp
+ const deltaTime = timestamp - lastTimestamp
+ lastTimestamp = timestamp
+
+ if (!isPaused) {
+ scrollPosition += scrollSpeed * (deltaTime / 16)
+
+ // 璁$畻鏈�澶ф粴鍔ㄤ綅缃紙鍘熷鍐呭鐨勯珮搴︼級
+ const maxScroll = itemHeight * originalItemCount
+
+ // 褰撴粴鍔ㄨ秴杩囧師濮嬪唴瀹归暱搴︽椂锛岄噸缃綅缃疄鐜版棤缂濇粴鍔�
+ if (scrollPosition >= maxScroll) {
+ scrollPosition = 0
+ tableContainer.scrollTop = 0
+ } else {
+ tableContainer.scrollTop = scrollPosition
+ }
+ }
+
+ progressTableScrollTimer.value = requestAnimationFrame(scrollAnimation)
+ }
+
+ // 鍚姩婊氬姩鍔ㄧ敾
+ progressTableScrollTimer.value = requestAnimationFrame(scrollAnimation)
+
+ // 璁剧疆婊氬姩-鏆傚仠-婊氬姩鐨勫惊鐜晥鏋�
+ const pauseTimer = setInterval(() => {
+ isPaused = !isPaused
+ }, pauseTime)
+
+ // 娓呯悊瀹氭椂鍣�
+ tableContainer._pauseTimer = pauseTimer
+}
+
// 鍒濆鍖栧緟鍔炰簨椤瑰垪琛ㄦ粴鍔ㄥ姛鑳�
const initTodoListScroll = () => {
const todoList = refTodoList.value
@@ -1031,6 +1383,7 @@
window.addEventListener('webkitfullscreenchange', handleFullscreenChange)
window.addEventListener('MSFullscreenChange', handleFullscreenChange)
analysisCustomer()
+ workInProcessTurnoverInfo()
qualityStatisticsInfo()
// accountStatisticsInfo()
progressStatisticsInfo()
@@ -1072,6 +1425,25 @@
clearInterval(todoList._pauseTimer)
todoList._pauseTimer = null
}
+ }
+
+ // 娓呯悊鐢熶骇璁㈠崟杩涘害琛ㄦ牸鐨勫姩鐢诲拰瀹氭椂鍣�
+ const progressTable = progressTableRef.value
+ if (progressTable) {
+ if (progressTableScrollTimer.value) {
+ cancelAnimationFrame(progressTableScrollTimer.value)
+ progressTableScrollTimer.value = null
+ }
+ if (progressTable._pauseTimer) {
+ clearInterval(progressTable._pauseTimer)
+ progressTable._pauseTimer = null
+ }
+ }
+
+ // 娓呯悊琛ㄦ牸婊氬姩瀹氭椂鍣�
+ if (tableScrollTimeout.value) {
+ clearTimeout(tableScrollTimeout.value)
+ tableScrollTimeout.value = null
}
// 娓呯悊鑷姩杞崲鍛ㄣ�佹湀銆佸搴︾殑瀹氭椂鍣�
@@ -1272,7 +1644,33 @@
}
.quality-card.three {
background-image: url("@/assets/BI/chuchangyijianicon@2x.png");
-
+}
+
+/* 璁㈠崟缁熻鍗$墖鏍峰紡 */
+.order-statistics-cards {
+ display: flex;
+ gap: 12px;
+ width: 100%;
+ height: 94px;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 20px;
+}
+
+.quality-card.four {
+ background-image: url("@/assets/BI/yuancailiaoyijianicon@2x.png");
+}
+
+.quality-card.five {
+ background-image: url("@/assets/BI/guochengyijianicon@2x.png");
+}
+
+.quality-card.six {
+ background-image: url("@/assets/BI/chuchangyijianicon@2x.png");
+}
+
+.quality-card.seven {
+ background-image: url("@/assets/BI/yuancailiaoyijianicon@2x.png");
}
.panel-title-icon {
width: 60px;
@@ -1555,4 +1953,84 @@
border-color: rgba(255, 255, 255, 0.5);
box-shadow: -1px 0 0 0 rgba(255, 255, 255, 0.5);
}
+
+/* 鐢熶骇璁㈠崟杩涘害琛ㄦ牸鏍峰紡 */
+.progress-table-container {
+ height: 250px;
+ overflow-y: auto;
+ overflow-x: hidden;
+ margin-top: 10px;
+ scrollbar-width: none; /* Firefox */
+ -ms-overflow-style: none; /* IE鍜孍dge */
+}
+
+.progress-table-container::-webkit-scrollbar {
+ display: none; /* Chrome銆丼afari鍜孫pera */
+}
+
+.progress-table {
+ width: 100%;
+ border-collapse: collapse;
+ color: #B8C8E0;
+ font-size: 12px;
+ table-layout: fixed;
+}
+
+.progress-table thead {
+ position: sticky;
+ top: 0;
+ background-color: rgba(26, 88, 176, 0.9);
+ z-index: 10;
+}
+
+.progress-table th {
+ padding: 8px 6px;
+ text-align: left;
+ font-weight: 500;
+ border-bottom: 1px solid rgba(184, 200, 224, 0.3);
+ color: #B8C8E0;
+ font-size: 12px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.progress-table th:nth-child(1) { width: 15%; } /* 鐢熶骇璁㈠崟鍙� */
+.progress-table th:nth-child(2) { width: 15%; } /* 浜у搧鍚嶇О */
+.progress-table th:nth-child(3) { width: 15%; } /* 瑙勬牸 */
+.progress-table th:nth-child(4) { width: 12%; } /* 闇�姹傛暟閲� */
+.progress-table th:nth-child(5) { width: 12%; } /* 瀹屾垚鏁伴噺 */
+.progress-table th:nth-child(6) { width: 31%; } /* 瀹屾垚杩涘害 */
+
+.progress-table td {
+ padding: 8px 6px;
+ border-bottom: 1px solid rgba(184, 200, 224, 0.1);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ font-size: 12px;
+ transition: opacity 0.3s ease;
+}
+
+.progress-table tbody tr:hover {
+ background-color: rgba(184, 200, 224, 0.1);
+}
+
+.progress-table tbody tr.row-under-header {
+ opacity: 0.5;
+}
+
+/* el-progress 缁勪欢鏍峰紡璋冩暣 */
+.progress-table :deep(.el-progress) {
+ width: 100%;
+}
+
+.progress-table :deep(.el-progress-bar__outer) {
+ background-color: rgba(184, 200, 224, 0.2);
+}
+
+.progress-table :deep(.el-progress__text) {
+ color: #B8C8E0;
+ font-size: 11px;
+}
</style>
\ No newline at end of file
diff --git a/src/views/reportAnalysis/projectProfit/index.vue b/src/views/reportAnalysis/projectProfit/index.vue
index 1aa36c1..f61cbe5 100644
--- a/src/views/reportAnalysis/projectProfit/index.vue
+++ b/src/views/reportAnalysis/projectProfit/index.vue
@@ -1,30 +1,32 @@
<template>
- <div class="app-container">
- <el-form :model="filters" :inline="true" label-width="80px">
- <el-form-item label="瀹㈡埛鍚嶇О">
- <el-input v-model="filters.customerName" placeholder="璇疯緭鍏ュ鎴峰悕绉�" />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="getTableData"> 鎼滅储 </el-button>
- <el-button @click="resetFilters"> 閲嶇疆 </el-button>
- <el-button @click="handleOut"> 瀵煎嚭 </el-button>
- </el-form-item>
- </el-form>
- <div class="table_list">
- <PIMTable
- rowKey="id"
- :column="columns"
- :tableLoading="loading"
- :tableData="dataList"
- :page="{
+ <div class="app-container">
+ <el-form :model="filters" :inline="true" label-width="80px">
+ <el-form-item label="瀹㈡埛鍚嶇О">
+ <el-input v-model="filters.customerName" placeholder="璇疯緭鍏ュ鎴峰悕绉�" clearable style="width: 240px"/>
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary" @click="getTableData"> 鎼滅储 </el-button>
+ <el-button @click="resetFilters"> 閲嶇疆 </el-button>
+ <el-button @click="handleOut"> 瀵煎嚭 </el-button>
+ </el-form-item>
+ </el-form>
+ <div class="table_list">
+ <PIMTable
+ rowKey="id"
+ :column="columns"
+ :tableLoading="loading"
+ :tableData="dataList"
+ :page="{
current: pagination.currentPage,
size: pagination.pageSize,
- total: pagination.total,
+ total: pagination.total
}"
- @pagination="changePage"
- ></PIMTable>
- </div>
- </div>
+ :isShowSummary="true"
+ :summaryMethod="summarizeMainTable"
+ @pagination="changePage"
+ ></PIMTable>
+ </div>
+ </div>
</template>
<script setup>
@@ -36,93 +38,89 @@
const { proxy } = getCurrentInstance();
defineOptions({
- name: "椤圭洰鍒╂鼎",
+ name: "椤圭洰鍒╂鼎",
});
const {
- loading,
- filters,
- columns,
- dataList,
- pagination,
- getTableData,
- resetFilters,
- onCurrentChange,
+ loading,
+ filters,
+ columns,
+ dataList,
+ pagination,
+ getTableData,
+ resetFilters,
+ onCurrentChange,
} = usePaginationApi(
- getPurchaseList,
- {
- customerName: undefined,
- },
- [
- {
- label: "閿�鍞悎鍚屽彿",
- align: "center",
- prop: "customerContractNo",
- },
- {
- label: "瀹㈡埛鍚嶇О",
- align: "center",
- prop: "customerName",
- },
- {
- label: "椤圭洰鍚嶇О",
- align: "center",
- prop: "projectName",
- },
- {
- label: "鍚堝悓閲戦",
- align: "center",
- prop: "contractAmount",
- },
- {
- label: "閲囪喘閲戦",
- align: "center",
- prop: "purchaseAmount",
- },
- {
- label: "鍒╂鼎",
- align: "center",
- prop: "balance",
- },
- {
- label: "鍒╂鼎鐜�",
- align: "center",
- prop: "balanceRatio",
- },
- {
- label: "澧炲�肩◣",
- align: "center",
- prop: "balanceAmount",
- },
- ]
+ getPurchaseList,
+ {
+ customerName: undefined,
+ },
+ [
+ {
+ label: "閿�鍞悎鍚屽彿",
+ align: "center",
+ prop: "customerContractNo",
+ },
+ {
+ label: "瀹㈡埛鍚嶇О",
+ align: "center",
+ prop: "customerName",
+ },
+ {
+ label: "鍚堝悓閲戦",
+ align: "center",
+ prop: "contractAmount",
+ },
+ {
+ label: "閲囪喘閲戦",
+ align: "center",
+ prop: "purchaseAmount",
+ },
+ {
+ label: "鍒╂鼎",
+ align: "center",
+ prop: "balance",
+ },
+ {
+ label: "鍒╂鼎鐜�",
+ align: "center",
+ prop: "balanceRatio",
+ },
+ ]
);
-const changePage = ({ page }) => {
- pagination.currentPage = page;
- onCurrentChange(page);
+const changePage = ({ page, limit }) => {
+ pagination.currentPage = page;
+ pagination.pageSize = limit;
+ onCurrentChange(page);
+};
+
+// 涓昏〃鍚堣鏂规硶
+const summarizeMainTable = (param) => {
+ return proxy.summarizeTable(param, ["contractAmount", "purchaseAmount", "balance"]);
};
// 瀵煎嚭
const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/purchase/report/export", {}, "椤圭洰鍒╂鼎.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ proxy.download("/purchase/report/export", {}, "椤圭洰鍒╂鼎.xlsx");
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
};
onMounted(() => {
- getTableData();
+ getTableData();
});
</script>
<style lang="scss" scoped>
.table_list {
- margin-top: unset;
+ margin-top: unset;
}
</style>
diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index 5304faf..18f8cc5 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -359,7 +359,7 @@
<span class="value">{{ formatDate(item.createTime) }}</span>
</div>
<div>
-
+
<span class="label">瀹㈡埛鍚嶇О锛�</span>
<span class="value">{{ item.customerName || '寮犵埍鏈�' }}</span>
</div>
@@ -490,16 +490,55 @@
</div>
</template>
</el-dialog>
- <FileList ref="fileListRef" />
+ <FileListDialog ref="fileListRef" v-model="fileListDialogVisible" />
+ <!-- 瀵煎叆瀵硅瘽妗� -->
+ <el-dialog
+ :title="importUpload.title"
+ v-model="importUpload.open"
+ width="400px"
+ append-to-body
+ >
+ <el-upload
+ ref="importUploadRef"
+ :limit="1"
+ accept=".xlsx, .xls"
+ :headers="importUpload.headers"
+ :action="importUpload.url"
+ :disabled="importUpload.isUploading"
+ :before-upload="importUpload.beforeUpload"
+ :on-progress="importUpload.onProgress"
+ :on-success="importUpload.onSuccess"
+ :on-error="importUpload.onError"
+ :on-change="importUpload.onChange"
+ :auto-upload="false"
+ drag
+ >
+ <el-icon class="el-icon--upload"><UploadFilled /></el-icon>
+ <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+ <template #tip>
+ <div class="el-upload__tip text-center">
+ <span>浠呭厑璁稿鍏ls銆亁lsx鏍煎紡鏂囦欢銆�</span>
+ </div>
+ </template>
+ </el-upload>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitImportFile" :loading="importUpload.isUploading">纭� 瀹�</el-button>
+ <el-button @click="importUpload.open = false">鍙� 娑�</el-button>
+ </div>
+ </template>
+ </el-dialog>
</div>
</template>
<script setup>
import { getToken } from "@/utils/auth";
import pagination from "@/components/PIMTable/Pagination.vue";
-import {onMounted, ref} from "vue";
+import {onMounted, ref, getCurrentInstance} from "vue";
import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js";
import {ElMessage, ElMessageBox} from "element-plus";
+import { ElMessageBox, ElMessage } from "element-plus";
+import { UploadFilled } from "@element-plus/icons-vue";
import useUserStore from "@/store/modules/user";
import { userListNoPage } from "@/api/system/user.js";
import FileList from "./fileList.vue";
@@ -650,6 +689,54 @@
});
const { deliveryForm, deliveryRules } = toRefs(deliveryFormData);
+// 瀵煎叆鐩稿叧
+const importUploadRef = ref(null);
+const importUpload = reactive({
+ title: "瀵煎叆閿�鍞彴璐�",
+ open: false,
+ url: import.meta.env.VITE_APP_BASE_API + "/sales/ledger/import",
+ headers: { Authorization: "Bearer " + getToken() },
+ isUploading: false,
+ beforeUpload: (file) => {
+ const isExcel = file.name.endsWith('.xlsx') || file.name.endsWith('.xls');
+ const isLt10M = file.size / 1024 / 1024 < 10;
+ if (!isExcel) {
+ proxy.$modal.msgError("涓婁紶鏂囦欢鍙兘鏄� xlsx/xls 鏍煎紡!");
+ return false;
+ }
+ if (!isLt10M) {
+ proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃 10MB!");
+ return false;
+ }
+ return true;
+ },
+ onChange: (file, fileList) => {
+ console.log('鏂囦欢鐘舵�佹敼鍙�', file, fileList);
+ },
+ onProgress: (event, file, fileList) => {
+ console.log('涓婁紶涓�...', event.percent);
+ },
+ onSuccess: (response, file, fileList) => {
+ console.log('涓婁紶鎴愬姛', response, file, fileList);
+ importUpload.isUploading = false;
+ if (response.code === 200) {
+ proxy.$modal.msgSuccess("瀵煎叆鎴愬姛");
+ importUpload.open = false;
+ if (importUploadRef.value) {
+ importUploadRef.value.clearFiles();
+ }
+ getList();
+ } else {
+ proxy.$modal.msgError(response.msg || "瀵煎叆澶辫触");
+ }
+ },
+ onError: (error, file, fileList) => {
+ console.error('涓婁紶澶辫触', error, file, fileList);
+ importUpload.isUploading = false;
+ proxy.$modal.msgError("瀵煎叆澶辫触锛岃閲嶈瘯");
+ },
+});
+
const changeDaterange = (value) => {
if (value) {
searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
@@ -708,7 +795,6 @@
});
};
const getProductModel = (value) => {
- console.log("value", value);
const index = modelOptions.value.findIndex((item) => item.id === value);
if (index !== -1) {
productForm.value.specificationModel = modelOptions.value[index].model;
@@ -733,6 +819,7 @@
return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
};
function convertIdToValue(data) {
+ if (!data || !Array.isArray(data)) return [];
return data.map((item) => {
const { id, children, ...rest } = item;
const newItem = {
@@ -902,6 +989,12 @@
productOperationType.value = type;
productForm.value = {};
proxy.resetForm("productFormRef");
+ // 鏂板銆佺紪杈戦兘闇�鍏堝姞杞戒骇鍝佹爲锛屽惁鍒� el-tree-select 鏃犳暟鎹�
+ try {
+ await getProductOptions();
+ } catch (e) {
+ console.error("鍔犺浇浜у搧鏍戝け璐�", e);
+ }
if (type === "edit") {
productForm.value = { ...row };
productIndex.value = index;
@@ -983,6 +1076,21 @@
proxy.resetForm("productFormRef");
productFormVisible.value = false;
};
+// 瀵煎叆
+const handleImport = () => {
+ importUpload.title = "瀵煎叆閿�鍞彴璐�";
+ importUpload.open = true;
+ if (importUploadRef.value) {
+ importUploadRef.value.clearFiles();
+ }
+};
+
+// 鎻愪氦瀵煎叆鏂囦欢
+const submitImportFile = () => {
+ importUpload.isUploading = true;
+ proxy.$refs["importUploadRef"].submit();
+};
+
// 瀵煎嚭
const handleOut = () => {
ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
--
Gitblit v1.9.3