From 4d3882045d317ddb3c7416f606ac738ca6ec2c01 Mon Sep 17 00:00:00 2001 From: gaoluyang <2820782392@qq.com> Date: 星期三, 23 七月 2025 10:21:05 +0800 Subject: [PATCH] 1.生产管理联调 --- src/views/productionManagement/operationScheduling/components/formDia.vue | 268 +++++---- src/views/productionManagement/productionReporting/index.vue | 426 +++++++++++++++ src/api/productionManagement/operationScheduling.js | 27 + src/views/productionManagement/productionCosting/index.vue | 183 ++++++ src/views/productionManagement/productionOrder/index.vue | 74 +- src/api/productionManagement/productionReporting.js | 35 + src/api/productionManagement/productionOrder.js | 19 src/views/productionManagement/productionDispatching/components/formDia.vue | 130 ++-- src/views/productionManagement/productionDispatching/index.vue | 111 +-- src/views/productionManagement/operationScheduling/index.vue | 133 ++-- src/views/productionManagement/productionReporting/components/formDia.vue | 155 +++++ 11 files changed, 1,218 insertions(+), 343 deletions(-) diff --git a/src/api/productionManagement/operationScheduling.js b/src/api/productionManagement/operationScheduling.js new file mode 100644 index 0000000..75ffe2a --- /dev/null +++ b/src/api/productionManagement/operationScheduling.js @@ -0,0 +1,27 @@ +// 宸ュ簭鎺掍骇椤甸潰鎺ュ彛 +import request from "@/utils/request"; + +// 鍒嗛〉鏌ヨ +export function listPageProcess(query) { + return request({ + url: "/salesLedger/scheduling/listPageProcess", + method: "get", + params: query, + }); +} +// 鍙栨秷鎺掍骇 +export function productionDispatchDelete(query) { + return request({ + url: "/salesLedger/scheduling/productionDispatchDelete", + method: "delete", + data: query, + }); +} +// 鍙栨秷鎺掍骇 +export function processScheduling(query) { + return request({ + url: "/salesLedger/scheduling/processScheduling", + method: "post", + data: query, + }); +} \ No newline at end of file diff --git a/src/api/productionManagement/productionOrder.js b/src/api/productionManagement/productionOrder.js new file mode 100644 index 0000000..ab3dc06 --- /dev/null +++ b/src/api/productionManagement/productionOrder.js @@ -0,0 +1,19 @@ +// 鐢熶骇璁㈠崟椤甸潰鎺ュ彛 +import request from "@/utils/request"; + +// 鍒嗛〉鏌ヨ +export function schedulingListPage(query) { + return request({ + url: "/salesLedger/scheduling/listPage", + method: "get", + params: query, + }); +} +// 鐢熶骇娲惧伐 +export function productionDispatch(query) { + return request({ + url: "/salesLedger/scheduling/productionDispatch", + method: "post", + data: query, + }); +} \ No newline at end of file diff --git a/src/api/productionManagement/productionReporting.js b/src/api/productionManagement/productionReporting.js new file mode 100644 index 0000000..fdec712 --- /dev/null +++ b/src/api/productionManagement/productionReporting.js @@ -0,0 +1,35 @@ +// 鐢熶骇鎶ュ伐椤甸潰鎺ュ彛 +import request from "@/utils/request"; + +// 鍒嗛〉鏌ヨ +export function workListPage(query) { + return request({ + url: "/salesLedger/work/listPage", + method: "get", + params: query, + }); +} +// 瀛愯〃鏍兼煡璇� +export function workListPageById(query) { + return request({ + url: "/salesLedger/work/list", + method: "get", + params: query, + }); +} +// 鐢熶骇鎶ュ伐 +export function productionReport(query) { + return request({ + url: "/salesLedger/work/productionReport", + method: "post", + data: query, + }); +} +// 鐢熶骇鎶ュ伐-缂栬緫 +export function productionReportUpdate(query) { + return request({ + url: "/salesLedger/work/productionReportUpdate", + method: "post", + data: query, + }); +} \ No newline at end of file diff --git a/src/views/productionManagement/operationScheduling/components/formDia.vue b/src/views/productionManagement/operationScheduling/components/formDia.vue index 9e5f1eb..ad37c4b 100644 --- a/src/views/productionManagement/operationScheduling/components/formDia.vue +++ b/src/views/productionManagement/operationScheduling/components/formDia.vue @@ -2,162 +2,182 @@ <div> <el-dialog v-model="dialogFormVisible" - :title="operationType === 'add' ? '鏂板鍏ヨ亴' : '缂栬緫浜哄憳'" + title="宸ュ簭鎺掍骇" width="70%" @close="closeDia" > - <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef"> - <el-row :gutter="30"> - <el-col :span="12"> - <el-form-item label="椤圭洰鍚嶇О锛�" prop="staffNo"> - <el-input v-model="form.staffNo" placeholder="璇疯緭鍏�" clearable disabled/> - </el-form-item> - </el-col> - <el-col :span="12"> - <el-form-item label="浜у搧澶х被锛�" prop="staffNo"> - <el-input v-model="form.staffNo" placeholder="璇疯緭鍏�" clearable disabled/> - </el-form-item> - </el-col> - </el-row> - <el-row :gutter="30"> - <el-col :span="12"> - <el-form-item label="鎬绘暟閲忥細" prop="staffNo"> - <el-input v-model="form.staffNo" placeholder="璇疯緭鍏�" clearable disabled/> - </el-form-item> - </el-col> - <el-col :span="12"> - <el-form-item label="鏈鎺掍骇鏁伴噺锛�" prop="staffNo"> - <el-input-number - v-model="form.ticketsNum" - placeholder="璇疯緭鍏�" - :min="0" - :step="0.1" - :precision="2" - clearable - style="width: 100%" + <el-button type="primary" @click="addRow" style="margin-bottom: 10px;">鏂板</el-button> + <span style="font-size: 18px;margin-left: 10px">寰呮帓浜ф暟閲忥細{{pendingNum}}</span> + <el-table :data="tableData" border style="width: 100%" :summary-method="summarizeMainTable" show-summary :row-key="row => row.id"> + <el-table-column label="搴忓彿" width="60"> + <template #default="scope"> + {{ scope.$index + 1 }} + </template> + </el-table-column> + <el-table-column label="宸ュ簭" prop="process"> + <template #default="scope"> + <el-select v-model="scope.row.process" placeholder="璇烽�夋嫨" clearable style="width: 100%"> + <el-option + v-for="dict in work_step" + :key="dict.value" + :label="dict.label" + :value="dict.value" /> - </el-form-item> - </el-col> - </el-row> - <el-row :gutter="30"> - <el-col :span="12"> - <el-form-item label="鎺掍骇浜猴細" prop="staffName"> - <el-input v-model="form.staffName" placeholder="璇疯緭鍏�" clearable/> - </el-form-item> - </el-col> - <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-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-select> + </template> + </el-table-column> + <el-table-column label="鍗曚綅" prop="unit"> + <template #default="scope"> + <el-input v-model="scope.row.unit" placeholder="璇疯緭鍏ュ崟浣�" /> + </template> + </el-table-column> + <el-table-column label="鎺掍骇鏁伴噺" width="200" prop="schedulingNum"> + <template #default="scope"> + <el-input-number + v-model="scope.row.schedulingNum" + placeholder="璇疯緭鍏�" + :min="0" + :step="0.1" + :precision="2" + clearable + style="width: 100%" + /> + </template> + </el-table-column> + <el-table-column label="宸ユ椂瀹氶" width="200" prop="workHours"> + <template #default="scope"> + <el-input-number + v-model="scope.row.workHours" + placeholder="璇疯緭鍏�" + :min="0" + :step="0.1" + :precision="2" + clearable + style="width: 100%" + /> + </template> + </el-table-column> + <el-table-column label="鎺掍骇鏃ユ湡" prop="schedulingDate"> + <template #default="scope"> + <el-date-picker v-model="scope.row.schedulingDate" type="date" placeholder="閫夋嫨鏃ユ湡" style="width: 100%;" value-format="YYYY-MM-DD" format="YYYY-MM-DD"/> + </template> + </el-table-column> + <el-table-column label="鎺掍骇浜�" prop="schedulingUserId"> + <template #default="scope"> + <el-select + v-model="scope.row.schedulingUserId" + placeholder="閫夋嫨浜哄憳" + style="width: 100%;" + > + <el-option + v-for="user in userList" + :key="user.userId" + :label="user.nickName" + :value="user.userId" + /> + </el-select> + </template> + </el-table-column> + <el-table-column label="鎿嶄綔" width="80"> + <template #default="scope"> + <el-button type="danger" size="small" @click="removeRow(scope.$index)">鍒犻櫎</el-button> + </template> + </el-table-column> + </el-table> + <template #footer> + <div class="dialog-footer"> + <el-button type="primary" @click="submitForm">纭</el-button> + <el-button @click="closeDia">鍙栨秷</el-button> + </div> + </template> </el-dialog> </div> </template> <script setup> import {ref} from "vue"; -import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js"; +import {userListNoPageByTenantId} from "@/api/system/user.js"; +import {processScheduling} from "@/api/productionManagement/operationScheduling.js"; const { proxy } = getCurrentInstance() +const { work_step } = proxy.useDict("work_step") const emit = defineEmits(['close']) const dialogFormVisible = ref(false); const operationType = ref('') -const data = reactive({ - form: { - staffNo: "", - staffName: "", - sex: "", - nativePlace: "", - postJob: "", - adress: "", - firstStudy: "", - profession: "", - identityCard: "", - age: 0, - phone: "", - emergencyContact: "", - emergencyContactPhone: "", - contractTerm: 0, - contractStartTime: "", - contractEndTime: "", - staffState: "", - }, - rules: { - staffNo: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },], - staffName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }], - sex: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }], - nativePlace: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }], - postJob: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }], - adress: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }], - firstStudy: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }], - profession: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }], - identityCard: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }], - age: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }], - phone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }], - emergencyContact: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }], - emergencyContactPhone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }], - contractTerm: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }], - contractStartTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }], - contractEndTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }], - }, -}); -const { form, rules } = toRefs(data); +const tableData = ref([ + { process: '', schedulingDate: '', schedulingNum: '', schedulingUserId: '', workHours: '', unit: '' } +]); +const unitFromRow = ref(''); +const idFromRow = ref(''); +const pendingNum = ref(''); +const userList = ref([]) // 鎵撳紑寮规 const openDialog = (type, row) => { operationType.value = type; dialogFormVisible.value = true; - if (operationType.value === 'edit') { - getStaffJoinInfo(row.id).then(res => { - form.value = {...res.data} - }) + userListNoPageByTenantId().then((res) => { + userList.value = res.data; + }); + pendingNum.value = row.pendingNum + if (row && row.unit !== undefined) { + unitFromRow.value = row.unit; + idFromRow.value = row.id; + tableData.value.forEach(item => { + item.unit = row.unit; + item.id = row.id; + }); + } else { + unitFromRow.value = ''; } } -// 鎻愪氦浜у搧琛ㄥ崟 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(); - }) - } - } - }) + // 1. 妫�鏌ユ瘡涓�琛屾槸鍚﹀~鍐欏畬鏁� + for (let i = 0; i < tableData.value.length; i++) { + const row = tableData.value[i]; + if ( + !row.process || + !row.schedulingDate || + row.schedulingNum === '' || row.schedulingNum === null || + !row.schedulingUserId || + row.workHours === '' || row.workHours === null || + !row.unit + ) { + proxy.$modal.msgError(`绗�${i + 1}琛屾暟鎹湭濉啓瀹屾暣`); + return; + } + } + // 2. 鍚堣鎺掍骇鏁伴噺 + const totalSchedulingNum = tableData.value.reduce((sum, row) => { + return sum + Number(row.schedulingNum || 0); + }, 0); + if (totalSchedulingNum > Number(pendingNum.value)) { + proxy.$modal.msgError('鎺掍骇鏁伴噺鍚堣涓嶈兘瓒呰繃寰呮帓浜ф暟閲�'); + return; + } + processScheduling(tableData.value).then((res) => { + proxy.$modal.msgSuccess("鎻愪氦鎴愬姛"); + closeDia(); + }) } - +const summarizeMainTable = (param) => { + return proxy.summarizeTable(param, ['schedulingNum']); +}; // 鍏抽棴寮规 const closeDia = () => { - proxy.resetForm("formRef"); dialogFormVisible.value = false; emit('close') }; defineExpose({ openDialog, }); + +const addRow = () => { + tableData.value.push({ id: idFromRow.value, process: '', unit: unitFromRow.value, schedulingNum: '', workHours: '', schedulingDate: '', schedulingUserId: '' }); +}; +const removeRow = (index) => { + tableData.value.splice(index, 1); +}; </script> <style scoped> diff --git a/src/views/productionManagement/operationScheduling/index.vue b/src/views/productionManagement/operationScheduling/index.vue index ca4bae6..3b35180 100644 --- a/src/views/productionManagement/operationScheduling/index.vue +++ b/src/views/productionManagement/operationScheduling/index.vue @@ -16,8 +16,9 @@ </el-form-item> <el-form-item label="鐘舵��:"> <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鐘舵��" style="width: 140px" clearable> - <el-option label="宸叉帓浜�" :value="1"></el-option> - <el-option label="寰呮帓浜�" :value="0"></el-option> + <el-option label="寰呮帓浜�" :value="1"></el-option> + <el-option label="宸叉帓浜�" :value="0"></el-option> + <el-option label="鎺掍骇涓�" :value="2"></el-option> </el-select> </el-form-item> <el-form-item> @@ -27,8 +28,8 @@ </div> <div class="table_list"> <div style="text-align: right" class="mb10"> - <el-button type="primary" @click="openForm('add')">宸ュ簭鎺掍骇</el-button> - <el-button type="danger" @click="openForm('delete')" plain>鍙栨秷鎺掍骇</el-button> + <el-button type="primary" @click="openForm">宸ュ簭鎺掍骇</el-button> + <el-button type="danger" @click="handleDelete" plain>鍙栨秷鎺掍骇</el-button> </div> <PIMTable rowKey="id" @@ -48,15 +49,15 @@ <script setup> import {onMounted, ref} from "vue"; -import FormDia from "@/views/productionManagement/productionDispatching/components/formDia.vue"; -import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js"; +import FormDia from "@/views/productionManagement/operationScheduling/components/formDia.vue"; import {ElMessageBox} from "element-plus"; import dayjs from "dayjs"; +import {listPageProcess, productionDispatchDelete} from "@/api/productionManagement/operationScheduling.js"; const data = reactive({ searchForm: { staffName: "", - status: 0, + status: 1, entryDate: [ dayjs().format("YYYY-MM-DD"), dayjs().add(1, "day").format("YYYY-MM-DD"), @@ -68,54 +69,83 @@ const { searchForm } = toRefs(data); const tableColumn = ref([ { - label: "褰曞叆鏃ユ湡", - prop: "staffNo", + label: "鐘舵��", + prop: "status", + dataType: "tag", + formatData: (params) => { + if (params == 0) { + return "宸叉帓浜�"; + } else if (params == 1) { + return "寰呮帓浜�"; + } else { + return '鎺掍骇涓�'; + } + }, + formatType: (params) => { + if (params == 0) { + return "success"; + } else if (params == 1) { + return "primary"; + } else { + return 'warning'; + } + }, + }, + { + label: "娲惧伐鏃ユ湡", + prop: "schedulingDate", + width: 120, + }, + { + label: "娲惧伐浜�", + prop: "schedulingUserName", }, { label: "鍚堝悓鍙�", - prop: "staffName", + prop: "salesContractNo", + width: 200, }, { label: "瀹㈡埛鍚堝悓鍙�", - prop: "addressPhone", - width: 250, + prop: "customerContractNo", + width: 200, }, { label: "瀹㈡埛鍚嶇О", - prop: "contactPerson", + prop: "customerName", + width: 200, }, { label: "椤圭洰鍚嶇О", - prop: "contactPhone", - width:150 + prop: "projectName", + width:300 }, { label: "浜у搧澶х被", - prop: "basicBankAccount", - width: 220, + prop: "productCategory", + width: 150, }, { label: "瑙勬牸鍨嬪彿", - prop: "bankAccount", - width: 220, + prop: "specificationModel", + width: 150, }, { label: "鍗曚綅", - prop: "bankCode", - width:220 + prop: "unit", }, { - label: "鏁伴噺", - prop: "maintainer", + label: "鎺掍骇鎬绘暟", + prop: "schedulingNum", }, { - label: "鎺掍骇鏁伴噺", - prop: "maintenanceTime", + label: "宸叉帓浜ф暟閲�", + prop: "successNum", width: 100, }, { - label: "寰呮帓鏁伴噺", - prop: "maintenanceTime", + label: "寰呮帓浜ф暟閲�", + prop: "pendingNum", width: 100, }, ]); @@ -138,11 +168,11 @@ }; const changeDaterange = (value) => { if (value) { - searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD"); - searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD"); + searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD"); + searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD"); } else { - searchForm.entryDateStart = undefined; - searchForm.entryDateEnd = undefined; + searchForm.value.entryDateStart = undefined; + searchForm.value.entryDateEnd = undefined; } handleQuery(); }; @@ -153,9 +183,14 @@ }; const getList = () => { tableLoading.value = true; - staffJoinListPage({...page, ...searchForm.value}).then(res => { + const params = { ...searchForm.value, ...page }; + params.entryDate = undefined + listPageProcess(params).then(res => { tableLoading.value = false; - tableData.value = res.data.records + tableData.value = res.data.records.map(item => ({ + ...item, + pendingNum: (Number(item.schedulingNum) || 0) - (Number(item.successNum) || 0) + })); page.total = res.data.total; }).catch(err => { tableLoading.value = false; @@ -172,12 +207,12 @@ proxy.$message.error("璇烽�夋嫨涓�鏉℃暟鎹�"); return; } - if (selectedRows.value[0].unPaymentAmountTotal == 0) { - proxy.$message.warning("鏃犻渶鍐嶄粯娆�"); + if (selectedRows.value[0].pendingNum == 0) { + proxy.$message.warning("鏃犻渶鍐嶆帓浜�"); return; } nextTick(() => { - formDia.value?.openDialog(type, row) + formDia.value?.openDialog(type, selectedRows.value[0]) }) }; @@ -190,30 +225,18 @@ proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁"); return; } - ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", { + 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"); + tableLoading.value = true; + productionDispatchDelete(ids) + .then((res) => { + proxy.$modal.msgSuccess("鍙栨秷鎺掍骇鎴愬姛"); + getList(); + }) }) .catch(() => { proxy.$modal.msg("宸插彇娑�"); diff --git a/src/views/productionManagement/productionCosting/index.vue b/src/views/productionManagement/productionCosting/index.vue new file mode 100644 index 0000000..ed72bd5 --- /dev/null +++ b/src/views/productionManagement/productionCosting/index.vue @@ -0,0 +1,183 @@ +<template> + <div class="app-container"> + <div class="search_form"> + <div> + <span class="search_title">鐢熶骇鏃ユ湡锛�</span> + <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" + placeholder="璇烽�夋嫨" clearable @change="changeDaterange" /> + <span class="search_title ml10">鐢熶骇浜猴細</span> + <el-input + v-model="searchForm.customerName" + style="width: 240px" + placeholder="璇疯緭鍏�" + @change="handleQuery" + clearable + prefix-icon="Search" + /> + <el-button type="primary" @click="handleQuery" style="margin-left: 10px" + >鎼滅储</el-button + > + </div> + <div> + <el-button @click="handleOut">瀵煎嚭</el-button> + </div> + </div> + <div class="table_list"> + <PIMTable + rowKey="id" + :column="tableColumn" + :tableData="tableData" + :page="page" + :tableLoading="tableLoading" + @pagination="pagination" + ></PIMTable> + </div> + </div> +</template> + +<script setup> +import {onMounted, ref} from "vue"; +import { + listCustomer, +} from "@/api/basicData/customerFile.js"; +import { ElMessageBox } from "element-plus"; +import dayjs from "dayjs"; +const { proxy } = getCurrentInstance(); + +const tableColumn = ref([ + { + label: "鐢熶骇鏃ユ湡", + prop: "customerName", + width: 120, + }, + { + label: "鐢熶骇浜�", + prop: "customerName", + width: 120, + }, + { + label: "鍚堝悓鍙�", + prop: "taxpayerIdentificationNumber", + width: 220, + }, + { + label: "瀹㈡埛鍚堝悓鍙�", + prop: "addressPhone", + width: 250, + }, + { + label: "瀹㈡埛鍚嶇О", + prop: "contactPerson", + }, + { + label: "椤圭洰鍚嶇О", + prop: "contactPhone", + width:150 + }, + { + label: "浜у搧澶х被", + prop: "basicBankAccount", + width: 220, + }, + { + label: "瑙勬牸鍨嬪彿", + prop: "bankAccount", + width: 220, + }, + { + label: "鍗曚綅", + prop: "bankCode", + width:220 + }, + { + label: "宸ュ簭", + prop: "maintainer", + }, + { + label: "鐢熶骇鏁伴噺", + prop: "maintenanceTime", + width: 100, + }, + { + label: "宸ユ椂瀹氶", + prop: "maintenanceTime", + width: 100, + }, + { + label: "宸ヨ祫", + prop: "maintenanceTime", + width: 100, + }, +]); +const tableData = ref([]); +const tableLoading = ref(false); +const page = reactive({ + current: 1, + size: 100, + total: 0, +}); + +const data = reactive({ + searchForm: { + customerName: "", + entryDate: [ + dayjs().format("YYYY-MM-DD"), + dayjs().add(1, "day").format("YYYY-MM-DD"), + ], // 褰曞叆鏃ユ湡 + entryDateStart: dayjs().format("YYYY-MM-DD"), + entryDateEnd: dayjs().add(1, "day").format("YYYY-MM-DD"), + }, +}); +const { searchForm } = toRefs(data); + +// 鏌ヨ鍒楄〃 +/** 鎼滅储鎸夐挳鎿嶄綔 */ +const handleQuery = () => { + page.current = 1; + getList(); +}; +const pagination = (obj) => { + page.current = obj.page; + page.size = obj.limit; + getList(); +}; +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 getList = () => { + tableLoading.value = true; + listCustomer({ ...searchForm.value, ...page }).then((res) => { + tableLoading.value = false; + tableData.value = res.records; + page.total = res.total; + }); +}; + +// 瀵煎嚭 +const handleOut = () => { + ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", { + confirmButtonText: "纭", + cancelButtonText: "鍙栨秷", + type: "warning", + }) + .then(() => { + proxy.download("/basic/customer/export", {}, "鐢熶骇鏍哥畻.xlsx"); + }) + .catch(() => { + proxy.$modal.msg("宸插彇娑�"); + }); +}; + +onMounted(() => { + getList(); +}); +</script> + +<style scoped lang="scss"></style> diff --git a/src/views/productionManagement/productionDispatching/components/formDia.vue b/src/views/productionManagement/productionDispatching/components/formDia.vue index 9e5f1eb..b3be1e4 100644 --- a/src/views/productionManagement/productionDispatching/components/formDia.vue +++ b/src/views/productionManagement/productionDispatching/components/formDia.vue @@ -9,46 +9,65 @@ <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/> + <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectName"> + <el-input v-model="form.projectName" placeholder="璇疯緭鍏�" clearable disabled/> </el-form-item> </el-col> <el-col :span="12"> - <el-form-item label="浜у搧澶х被锛�" prop="staffNo"> - <el-input v-model="form.staffNo" placeholder="璇疯緭鍏�" clearable disabled/> + <el-form-item label="浜у搧澶х被锛�" prop="productCategory"> + <el-input v-model="form.productCategory" placeholder="璇疯緭鍏�" clearable disabled/> </el-form-item> </el-col> </el-row> <el-row :gutter="30"> <el-col :span="12"> - <el-form-item label="鎬绘暟閲忥細" prop="staffNo"> - <el-input v-model="form.staffNo" placeholder="璇疯緭鍏�" clearable disabled/> + <el-form-item label="鎬绘暟閲忥細" prop="quantity"> + <el-input v-model="form.quantity" placeholder="璇疯緭鍏�" clearable disabled/> </el-form-item> </el-col> <el-col :span="12"> - <el-form-item label="鏈鎺掍骇鏁伴噺锛�" prop="staffNo"> + <el-form-item label="寰呮帓浜ф暟閲忥細" prop="pendingQuantity"> + <el-input v-model="form.pendingQuantity" placeholder="璇疯緭鍏�" clearable disabled/> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="30"> + <el-col :span="12"> + <el-form-item label="鏈鎺掍骇鏁伴噺锛�" prop="schedulingNum"> <el-input-number - v-model="form.ticketsNum" + v-model="form.schedulingNum" placeholder="璇疯緭鍏�" :min="0" :step="0.1" :precision="2" clearable + @change="changeNum" style="width: 100%" /> - </el-form-item> + </el-form-item> </el-col> </el-row> <el-row :gutter="30"> <el-col :span="12"> - <el-form-item label="鎺掍骇浜猴細" prop="staffName"> - <el-input v-model="form.staffName" placeholder="璇疯緭鍏�" clearable/> + <el-form-item label="娲惧伐浜猴細" prop="schedulingUserId"> + <el-select + v-model="form.schedulingUserId" + placeholder="閫夋嫨浜哄憳" + style="width: 100%;" + > + <el-option + v-for="user in userList" + :key="user.userId" + :label="user.nickName" + :value="user.userId" + /> + </el-select> </el-form-item> </el-col> <el-col :span="12"> - <el-form-item label="鎺掍骇鏃ユ湡锛�" prop="contractStartTime"> + <el-form-item label="娲惧伐鏃ユ湡锛�" prop="schedulingDate"> <el-date-picker - v-model="form.contractStartTime" + v-model="form.schedulingDate" type="date" placeholder="璇烽�夋嫨鏃ユ湡" value-format="YYYY-MM-DD" @@ -73,6 +92,10 @@ <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"; +import dayjs from "dayjs"; const { proxy } = getCurrentInstance() const emit = defineEmits(['close']) @@ -80,71 +103,52 @@ const operationType = ref('') const data = reactive({ form: { - staffNo: "", - staffName: "", - sex: "", - nativePlace: "", - postJob: "", - adress: "", - firstStudy: "", - profession: "", - identityCard: "", - age: 0, - phone: "", - emergencyContact: "", - emergencyContactPhone: "", - contractTerm: 0, - contractStartTime: "", - contractEndTime: "", - staffState: "", + projectName: "", + productCategory: "", + quantity: "", + schedulingNum: "", + schedulingUserId: "", + schedulingDate: "", + pendingQuantity: "", }, 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" }], - identityCard: [{ 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" }], + schedulingNum: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },], + schedulingUserId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" },], + schedulingDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" },], }, }); const { form, rules } = toRefs(data); +const userList = ref([]) +const userStore = useUserStore() // 鎵撳紑寮规 const openDialog = (type, row) => { operationType.value = type; dialogFormVisible.value = true; - if (operationType.value === 'edit') { - getStaffJoinInfo(row.id).then(res => { - form.value = {...res.data} - }) - } + userListNoPageByTenantId().then((res) => { + userList.value = res.data; + }); + form.value = {...row} + form.value.schedulingNum = 0 + form.value.schedulingUserId = userStore.id + form.value.schedulingDate = dayjs().format("YYYY-MM-DD"); +} + +// +const changeNum = (value) => { + if (value > form.value.pendingQuantity) { + form.value.schedulingNum = form.value.pendingQuantity; + proxy.$modal.msgWarning('鎺掍骇鏁伴噺涓嶅彲澶т簬寰呮帓浜ф暟閲�') + } } // 鎻愪氦浜у搧琛ㄥ崟 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(); - }) - } + productionDispatch(form.value).then(res => { + proxy.$modal.msgSuccess("鎻愪氦鎴愬姛"); + closeDia(); + }) } }) } diff --git a/src/views/productionManagement/productionDispatching/index.vue b/src/views/productionManagement/productionDispatching/index.vue index 70a3de9..c28b062 100644 --- a/src/views/productionManagement/productionDispatching/index.vue +++ b/src/views/productionManagement/productionDispatching/index.vue @@ -23,9 +23,7 @@ <span class="search_title ml10">褰曞叆鏃ユ湡锛�</span> <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" placeholder="璇烽�夋嫨" clearable @change="changeDaterange" /> - <el-button type="primary" @click="handleQuery" style="margin-left: 10px" - >鎼滅储</el-button - > + <el-button type="primary" @click="handleQuery" style="margin-left: 10px">鎼滅储</el-button> </div> <div> <el-button type="primary" @click="openForm('add')">鐢熶骇娲惧伐</el-button> @@ -51,9 +49,8 @@ <script setup> import {onMounted, ref} from "vue"; import FormDia from "@/views/productionManagement/productionDispatching/components/formDia.vue"; -import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js"; -import {ElMessageBox} from "element-plus"; import dayjs from "dayjs"; +import {schedulingListPage} from "@/api/productionManagement/productionOrder.js"; const data = reactive({ searchForm: { @@ -70,53 +67,56 @@ const tableColumn = ref([ { label: "褰曞叆鏃ユ湡", - prop: "staffNo", + prop: "entryDate", + width: 120, }, { label: "鍚堝悓鍙�", - prop: "staffName", + prop: "salesContractNo", + width: 220, }, { label: "瀹㈡埛鍚堝悓鍙�", - prop: "addressPhone", + prop: "customerContractNo", width: 250, }, { label: "瀹㈡埛鍚嶇О", - prop: "contactPerson", + prop: "customerName", + width: 250, }, { label: "椤圭洰鍚嶇О", - prop: "contactPhone", - width:150 + prop: "projectName", + width:300 }, { label: "浜у搧澶х被", - prop: "basicBankAccount", - width: 220, + prop: "productCategory", + width: 160, }, { label: "瑙勬牸鍨嬪彿", - prop: "bankAccount", + prop: "specificationModel", width: 220, }, { label: "鍗曚綅", - prop: "bankCode", - width:220 + prop: "unit", + width:90 }, { label: "鏁伴噺", - prop: "maintainer", + prop: "quantity", }, { label: "鎺掍骇鏁伴噺", - prop: "maintenanceTime", + prop: "schedulingNum", width: 100, }, { label: "寰呮帓鏁伴噺", - prop: "maintenanceTime", + prop: "pendingQuantity", width: 100, }, ]); @@ -139,11 +139,11 @@ }; const changeDaterange = (value) => { if (value) { - searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD"); - searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD"); + searchForm.value.entryDateStart = value[0]; + searchForm.value.entryDateEnd = value[1]; } else { - searchForm.entryDateStart = undefined; - searchForm.entryDateEnd = undefined; + searchForm.value.entryDateStart = undefined; + searchForm.value.entryDateEnd = undefined; } handleQuery(); }; @@ -154,11 +154,18 @@ }; const getList = () => { tableLoading.value = true; - staffJoinListPage({...page, ...searchForm.value}).then(res => { + // 鏋勯�犱竴涓柊鐨勫璞★紝涓嶅寘鍚玡ntryDate瀛楁 + const params = { ...searchForm.value, ...page }; + params.entryDate = undefined + schedulingListPage(params).then((res) => { tableLoading.value = false; - tableData.value = res.data.records + // 澶勭悊姣忔潯鏁版嵁锛屽鍔爌endingQuantity瀛楁 + tableData.value = res.data.records.map(item => ({ + ...item, + pendingQuantity: (Number(item.quantity) || 0) - (Number(item.schedulingNum) || 0) + })); page.total = res.data.total; - }).catch(err => { + }).catch(() => { tableLoading.value = false; }) }; @@ -168,59 +175,27 @@ }; // 鎵撳紑寮规 -const openForm = (type, row) => { +const openForm = (type) => { if (selectedRows.value.length !== 1) { proxy.$message.error("璇烽�夋嫨涓�鏉℃暟鎹�"); return; } - if (selectedRows.value[0].unPaymentAmountTotal == 0) { - proxy.$message.warning("鏃犻渶鍐嶄粯娆�"); + if (selectedRows.value[0].pendingQuantity == 0) { + proxy.$message.warning("鏃犻渶鍐嶆淳宸�"); return; } nextTick(() => { - formDia.value?.openDialog(type, row) + formDia.value?.openDialog(type, selectedRows.value[0]) }) }; -// 鍒犻櫎 -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(() => { + searchForm.value.entryDate = [ + dayjs().format("YYYY-MM-DD"), + dayjs().add(1, "day").format("YYYY-MM-DD"), + ] + searchForm.value.entryDateStart = dayjs().format("YYYY-MM-DD") + searchForm.value.entryDateEnd = dayjs().add(1, "day").format("YYYY-MM-DD") getList(); }); </script> diff --git a/src/views/productionManagement/productionOrder/index.vue b/src/views/productionManagement/productionOrder/index.vue index 87ca041..e65fd3b 100644 --- a/src/views/productionManagement/productionOrder/index.vue +++ b/src/views/productionManagement/productionOrder/index.vue @@ -13,7 +13,7 @@ /> <span class="search_title ml10">椤圭洰鍚嶇О锛�</span> <el-input - v-model="searchForm.customerName" + v-model="searchForm.projectName" style="width: 240px" placeholder="璇疯緭鍏�" @change="handleQuery" @@ -46,65 +46,64 @@ <script setup> import {onMounted, ref} from "vue"; -import { - listCustomer, -} from "@/api/basicData/customerFile.js"; import { ElMessageBox } from "element-plus"; import dayjs from "dayjs"; +import {schedulingListPage} from "@/api/productionManagement/productionOrder.js"; const { proxy } = getCurrentInstance(); const tableColumn = ref([ { label: "褰曞叆鏃ユ湡", - prop: "customerName", + prop: "entryDate", width: 120, }, { label: "鍚堝悓鍙�", - prop: "taxpayerIdentificationNumber", + prop: "salesContractNo", width: 220, }, { label: "瀹㈡埛鍚堝悓鍙�", - prop: "addressPhone", + prop: "customerContractNo", width: 250, }, { label: "瀹㈡埛鍚嶇О", - prop: "contactPerson", + prop: "customerName", + width: 250, }, { label: "椤圭洰鍚嶇О", - prop: "contactPhone", - width:150 + prop: "projectName", + width:300 }, { label: "浜у搧澶х被", - prop: "basicBankAccount", - width: 220, + prop: "productCategory", + width: 160, }, { label: "瑙勬牸鍨嬪彿", - prop: "bankAccount", + prop: "specificationModel", width: 220, }, { label: "鍗曚綅", - prop: "bankCode", - width:220 + prop: "unit", + width:90 }, { label: "鏁伴噺", - prop: "maintainer", + prop: "quantity", }, { label: "鎺掍骇鏁伴噺", - prop: "maintenanceTime", + prop: "schedulingNum", width: 100, }, { label: "瀹屽伐鏁伴噺", - prop: "maintenanceTime", + prop: "successNum", width: 100, }, ]); @@ -119,12 +118,10 @@ const data = reactive({ searchForm: { customerName: "", - entryDate: [ - dayjs().format("YYYY-MM-DD"), - dayjs().add(1, "day").format("YYYY-MM-DD"), - ], // 褰曞叆鏃ユ湡 - entryDateStart: dayjs().format("YYYY-MM-DD"), - entryDateEnd: dayjs().add(1, "day").format("YYYY-MM-DD"), + projectName: "", + entryDate: [], // 褰曞叆鏃ユ湡 + entryDateStart: '', + entryDateEnd: '', }, }); const { searchForm } = toRefs(data); @@ -142,21 +139,26 @@ }; const changeDaterange = (value) => { if (value) { - searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD"); - searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD"); + searchForm.value.entryDateStart = value[0]; + searchForm.value.entryDateEnd = value[1]; } else { - searchForm.entryDateStart = undefined; - searchForm.entryDateEnd = undefined; + searchForm.value.entryDateStart = undefined; + searchForm.value.entryDateEnd = undefined; } handleQuery(); }; const getList = () => { tableLoading.value = true; - listCustomer({ ...searchForm.value, ...page }).then((res) => { + // 鏋勯�犱竴涓柊鐨勫璞★紝涓嶅寘鍚玡ntryDate瀛楁 + const params = { ...searchForm.value, ...page }; + params.entryDate = undefined + schedulingListPage(params).then((res) => { tableLoading.value = false; - tableData.value = res.records; - page.total = res.total; - }); + tableData.value = res.data.records; + page.total = res.data.total; + }).catch(() => { + tableLoading.value = false; + }) }; // 瀵煎嚭 @@ -167,7 +169,7 @@ type: "warning", }) .then(() => { - proxy.download("/basic/customer/export", {}, "瀹㈡埛妗f.xlsx"); + proxy.download("/salesLedger/scheduling/export", {}, "鐢熶骇璁㈠崟.xlsx"); }) .catch(() => { proxy.$modal.msg("宸插彇娑�"); @@ -175,6 +177,12 @@ }; onMounted(() => { + searchForm.value.entryDate = [ + dayjs().format("YYYY-MM-DD"), + dayjs().add(1, "day").format("YYYY-MM-DD"), + ] + searchForm.value.entryDateStart = dayjs().format("YYYY-MM-DD") + searchForm.value.entryDateEnd = dayjs().add(1, "day").format("YYYY-MM-DD") getList(); }); </script> diff --git a/src/views/productionManagement/productionReporting/components/formDia.vue b/src/views/productionManagement/productionReporting/components/formDia.vue new file mode 100644 index 0000000..89f6c76 --- /dev/null +++ b/src/views/productionManagement/productionReporting/components/formDia.vue @@ -0,0 +1,155 @@ +<template> + <div> + <el-dialog + v-model="dialogFormVisible" + title="鐢熶骇鎶ュ伐" + width="70%" + @close="closeDia" + > + <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef"> + <el-row :gutter="30"> + <el-col :span="12"> + <el-form-item label="鎺掍骇鏁伴噺锛�" prop="schedulingNum"> + <el-input v-model="form.schedulingNum" placeholder="璇疯緭鍏�" clearable disabled/> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="鏈鐢熶骇鏁伴噺锛�" prop="finishedNum"> + <el-input-number + v-model="form.finishedNum" + placeholder="璇疯緭鍏�" + :min="0" + :step="0.1" + :precision="2" + clearable + style="width: 100%" + @change="changeNum" + /> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="30"> + <el-col :span="12"> + <el-form-item label="寰呯敓浜ф暟閲忥細" prop="pendingNum"> + <el-input v-model="form.pendingNum" placeholder="璇疯緭鍏�" clearable disabled/> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="30"> + <el-col :span="12"> + <el-form-item label="鐢熶骇浜猴細" prop="schedulingUserId"> + <el-select + v-model="form.schedulingUserId" + placeholder="閫夋嫨浜哄憳" + style="width: 100%;" + > + <el-option + v-for="user in userList" + :key="user.userId" + :label="user.nickName" + :value="user.userId" + /> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="鐢熶骇鏃ユ湡锛�" prop="schedulingDate"> + <el-date-picker + v-model="form.schedulingDate" + type="date" + placeholder="璇烽�夋嫨鏃ユ湡" + value-format="YYYY-MM-DD" + format="YYYY-MM-DD" + clearable + style="width: 100%" + /> + </el-form-item> + </el-col> + </el-row> + </el-form> + <template #footer> + <div class="dialog-footer"> + <el-button type="primary" @click="submitForm">纭</el-button> + <el-button @click="closeDia">鍙栨秷</el-button> + </div> + </template> + </el-dialog> + </div> +</template> + +<script setup> +import {ref} from "vue"; +import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js"; +import {userListNoPageByTenantId} from "@/api/system/user.js"; +import {productionReport, productionReportUpdate} from "@/api/productionManagement/productionReporting.js"; +const { proxy } = getCurrentInstance() +const emit = defineEmits(['close']) + +const userList = ref([]) +const dialogFormVisible = ref(false); +const operationType = ref('') +const data = reactive({ + form: { + successNum: "", + schedulingNum: "", + finishedNum: "", + schedulingUserId: "", + schedulingDate: "", + }, + rules: { + schedulingNum: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },], + }, +}); +const { form, rules } = toRefs(data); + +// 鎵撳紑寮规 +const openDialog = (type, row) => { + operationType.value = type; + dialogFormVisible.value = true; + userListNoPageByTenantId().then((res) => { + userList.value = res.data; + }); + form.value = {...row} +} + +const changeNum = (value) => { + if (value > form.value.schedulingNum) { + form.value.finishedNum = form.value.schedulingNum; + proxy.$modal.msgWarning('鏈鐢熶骇鏁伴噺涓嶅彲澶т簬鎺掍骇鏁伴噺') + } + form.value.pendingNum = form.value.schedulingNum - form.value.finishedNum; +} +// 鎻愪氦浜у搧琛ㄥ崟 +const submitForm = () => { + proxy.$refs.formRef.validate(valid => { + if (valid) { + form.value.staffState = 1 + if (operationType.value === "add") { + productionReport(form.value).then(res => { + proxy.$modal.msgSuccess("鎻愪氦鎴愬姛"); + closeDia(); + }) + } else { + productionReportUpdate(form.value).then(res => { + proxy.$modal.msgSuccess("鎻愪氦鎴愬姛"); + closeDia(); + }) + } + } + }) +} + +// 鍏抽棴寮规 +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/productionManagement/productionReporting/index.vue b/src/views/productionManagement/productionReporting/index.vue new file mode 100644 index 0000000..f65697d --- /dev/null +++ b/src/views/productionManagement/productionReporting/index.vue @@ -0,0 +1,426 @@ +<template> + <div class="app-container"> + <div class="search_form"> + <el-form :model="searchForm" :inline="true"> + <el-form-item label="瀹㈡埛鍚嶇О:"> + <el-input v-model="searchForm.customerName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search" + @change="handleQuery" /> + </el-form-item> + <el-form-item label="椤圭洰鍚嶇О:"> + <el-input v-model="searchForm.projectName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search" + @change="handleQuery" /> + </el-form-item> + <el-form-item label="鎺掍骇鏃ユ湡:"> + <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" + placeholder="璇烽�夋嫨" clearable @change="changeDaterange" /> + </el-form-item> + <el-form-item label="鐘舵��:"> + <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鐘舵��" style="width: 140px" clearable> + <el-option label="寰呯敓浜�" :value="1"></el-option> + <el-option label="宸叉姤宸�" :value="0"></el-option> + <el-option label="鐢熶骇涓�" :value="2"></el-option> + </el-select> + </el-form-item> + <el-form-item> + <el-button type="primary" @click="handleQuery">鎼滅储</el-button> + </el-form-item> + </el-form> + </div> + <div class="table_list"> + <div style="text-align: right" class="mb10"> + <el-button type="primary" @click="openForm('add')">鐢熶骇鎶ュ伐</el-button> + </div> + <PIMTable + rowKey="id" + :column="tableColumn" + :tableData="tableData" + :page="page" + :isSelection="true" + :expandRowKeys="expandedRowKeys" + @expand-change="expandChange" + @selection-change="handleSelectionChange" + :tableLoading="tableLoading" + @pagination="pagination" + :total="page.total" + > + <template #expand="{ row }"> + <el-table + :data="expandData" + border + show-summary + :summary-method="summarizeMainTable" + v-loading="childrenLoading" + > + <el-table-column + align="center" + label="搴忓彿" + type="index" + width="60" + /> + <el-table-column label="鏈鐢熶骇鏁伴噺" prop="finishedNum" align="center"> + <template #default="scope"> + <el-input-number :step="0.01" :min="0" style="width: 100%" + v-model="scope.row.finishedNum" + :disabled="!scope.row.editType" + :precision="2" + placeholder="璇疯緭鍏�" + clearable + @change="changeNum(scope.row)" + /> + </template> + </el-table-column> +<!-- <el-table-column label="寰呯敓浜ф暟閲�" prop="pendingNum" width="240" align="center"></el-table-column>--> + <el-table-column label="鐢熶骇浜�" prop="schedulingUserId" width="240"> + <template #default="scope"> + <el-select + v-model="scope.row.schedulingUserId" + placeholder="閫夋嫨浜哄憳" + :disabled="!scope.row.editType" + style="width: 100%;" + > + <el-option + v-for="user in userList" + :key="user.userId" + :label="user.nickName" + :value="user.userId" + /> + </el-select> + </template> + </el-table-column> + <el-table-column label="鐢熶骇鏃ユ湡" prop="schedulingDate" width="240"> + <template #default="scope"> + <el-date-picker + v-model="scope.row.schedulingDate" + type="date" + :disabled="!scope.row.editType" + placeholder="璇烽�夋嫨鏃ユ湡" + value-format="YYYY-MM-DD" + format="YYYY-MM-DD" + clearable + style="width: 100%" + /> + </template> + </el-table-column> + <el-table-column label="鎿嶄綔" width="60"> + <template #default="scope"> + <el-button + link + type="primary" + size="small" + @click="changeEditType(scope.row)" + v-if="!scope.row.editType" + >缂栬緫</el-button + > + <el-button + link + type="primary" + size="small" + @click="saveReceiptPayment(scope.row)" + v-if="scope.row.editType" + >淇濆瓨</el-button + > + </template> + </el-table-column> + </el-table> + </template> + </PIMTable> + </div> + <form-dia ref="formDia" @close="handleQuery"></form-dia> + </div> +</template> + +<script setup> +import {onMounted, ref} from "vue"; +import FormDia from "@/views/productionManagement/productionReporting/components/formDia.vue"; +import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js"; +import {ElMessageBox} from "element-plus"; +import dayjs from "dayjs"; +import { + productionReportUpdate, + workListPage, + workListPageById +} from "@/api/productionManagement/productionReporting.js"; +import {userListNoPageByTenantId} from "@/api/system/user.js"; + +const data = reactive({ + searchForm: { + staffName: "", + entryDate: [ + dayjs().format("YYYY-MM-DD"), + dayjs().add(1, "day").format("YYYY-MM-DD"), + ], // 褰曞叆鏃ユ湡 + entryDateStart: dayjs().format("YYYY-MM-DD"), + entryDateEnd: dayjs().add(1, "day").format("YYYY-MM-DD"), + }, +}); +const { searchForm } = toRefs(data); +const expandedRowKeys = ref([]); +const expandData = ref([]); +const userList = ref([]) +const tableColumn = ref([ + { + type: "expand", + dataType: "slot", + slot: "expand", + }, + { + label: "鐘舵��", + prop: "status", + dataType: "tag", + formatData: (params) => { + if (params == 0) { + return "宸叉姤宸�"; + } else if (params == 1) { + return "寰呯敓浜�"; + } else { + return '鐢熶骇涓�'; + } + }, + formatType: (params) => { + if (params == 0) { + return "success"; + } else if (params == 1) { + return "primary"; + } else { + return 'warning'; + } + }, + }, + { + label: "鎺掍骇鏃ユ湡", + prop: "schedulingDate", + width: 120, + }, + { + label: "鎺掍骇浜�", + prop: "schedulingUserName", + }, + { + label: "鍚堝悓鍙�", + prop: "salesContractNo", + width: 200, + }, + { + label: "瀹㈡埛鍚堝悓鍙�", + prop: "customerContractNo", + width: 200, + }, + { + label: "瀹㈡埛鍚嶇О", + prop: "customerName", + width: 200, + }, + { + label: "椤圭洰鍚嶇О", + prop: "projectName", + width:300 + }, + { + label: "浜у搧澶х被", + prop: "productCategory", + width: 150, + }, + { + label: "瑙勬牸鍨嬪彿", + prop: "specificationModel", + width: 150, + }, + { + label: "鍗曚綅", + prop: "unit", + }, + { + label: "宸ュ簭", + prop: "process", + }, + { + label: "鎺掍骇鏁伴噺", + prop: "schedulingNum", + width: 100, + }, + { + label: "鐢熶骇鏁伴噺", + prop: "finishedNum", + width: 100, + }, + { + label: "寰呯敓浜ф暟閲�", + prop: "pendingFinishNum", + width: 100, + }, +]); +const tableData = ref([]); +const selectedRows = ref([]); +const tableLoading = ref(false); +const childrenLoading = ref(false); +const page = reactive({ + current: 1, + size: 100, + total: 0, +}); +const formDia = ref() +const { proxy } = getCurrentInstance() + +// 鏌ヨ鍒楄〃 +/** 鎼滅储鎸夐挳鎿嶄綔 */ +const handleQuery = () => { + page.current = 1; + getList(); +}; +const changeDaterange = (value) => { + if (value) { + searchForm.value.entryDateStart = value[0]; + searchForm.value.entryDateEnd = value[1]; + } else { + searchForm.value.entryDateStart = undefined; + searchForm.value.entryDateEnd = undefined; + } + handleQuery(); +}; +const pagination = (obj) => { + page.current = obj.page; + page.size = obj.limit; + getList(); +}; +const getList = () => { + tableLoading.value = true; + const params = { ...searchForm.value, ...page }; + params.entryDate = undefined + expandedRowKeys.value = [] + workListPage(params).then(res => { + tableLoading.value = false; + tableData.value = res.data.records.map(item => ({ + ...item, + pendingFinishNum: (Number(item.schedulingNum) || 0) - (Number(item.finishedNum) || 0) + })); + page.total = res.data.total; + }).catch(err => { + tableLoading.value = false; + }) +}; +// 灞曞紑琛� +const expandChange = (row, expandedRows) => { + userListNoPageByTenantId().then((res) => { + userList.value = res.data; + }); + if (expandedRows.length > 0) { + nextTick(() => { + expandedRowKeys.value = []; + try { + childrenLoading.value = true; + workListPageById({ id: row.id }).then((res) => { + childrenLoading.value = false; + const index = tableData.value.findIndex((item) => item.id === row.id); + if (index > -1) { + expandData.value = res.data.map(item => ({ + ...item, + pendingNum: (Number(item.schedulingNum) || 0) - (Number(item.finishedNum) || 0) + })); + } + expandedRowKeys.value.push(row.id); + }); + } catch (error) { + childrenLoading.value = false; + console.log(error); + } + }) + } else { + expandedRowKeys.value = []; + } +}; +const changeNum = (row) => { + // 鎵惧埌鐖惰〃鏍兼暟鎹� + const parentRow = tableData.value.find(item => item.id === expandedRowKeys.value[0]); + // 璁$畻鎵�鏈夊瓙琛ㄦ牸 finishedNum 鐨勬�诲拰 + const totalFinishedNum = expandData.value.reduce((sum, item) => sum + (Number(item.finishedNum) || 0), 0); + // 鐖惰〃鏍肩殑鎺掍骇鏁伴噺 + const schedulingNum = parentRow ? Number(parentRow.schedulingNum) : 0; + + if (totalFinishedNum > schedulingNum) { + // 鍥為��鏈杈撳叆 + row.finishedNum = schedulingNum - (totalFinishedNum - Number(row.finishedNum)); + proxy.$modal.msgWarning('鎵�鏈夋湰娆$敓浜ф暟閲忎箣鍜屼笉鍙ぇ浜庢帓浜ф暟閲�'); + } + row.pendingNum = row.schedulingNum - row.finishedNum; +} +// 缂栬緫淇敼鐘舵�� +const changeEditType = (row) => { + row.editType = !row.editType; +}; +// 淇濆瓨璁板綍 +const saveReceiptPayment = (row) => { + productionReportUpdate(row).then((res) => { + row.editType = !row.editType; + getList(); + proxy.$modal.msgSuccess("鎻愪氦鎴愬姛"); + }); +}; +// 琛ㄦ牸閫夋嫨鏁版嵁 +const handleSelectionChange = (selection) => { + selectedRows.value = selection; +}; +const summarizeMainTable = (param) => { + return proxy.summarizeTable(param, [ + "finishedNum" + ]); +}; +// 鎵撳紑寮规 +const openForm = (type, row) => { + if (selectedRows.value.length !== 1) { + proxy.$message.error("璇烽�夋嫨涓�鏉℃暟鎹�"); + return; + } + if (selectedRows.value[0].pendingFinishNum == 0) { + proxy.$message.warning("鏃犻渶鍐嶆姤宸�"); + return; + } + nextTick(() => { + const rowInfo = type === 'add' ? selectedRows.value[0] : row + formDia.value?.openDialog(type, rowInfo) + }) +}; + +// 鍒犻櫎 +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> -- Gitblit v1.9.3