From 0c4bdf3dca76f9b8c348f2f7e48f9a6319dee4e1 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期五, 17 四月 2026 17:09:22 +0800
Subject: [PATCH] 进销存升级 1.销售台账不能删除和编辑别人维护的数据 2.产品维护固定产品大类为:成品、半成品、原材料。

---
 src/views/productionManagement/productionCosting/index.vue |  355 ++++++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 266 insertions(+), 89 deletions(-)

diff --git a/src/views/productionManagement/productionCosting/index.vue b/src/views/productionManagement/productionCosting/index.vue
index a597317..fc93570 100644
--- a/src/views/productionManagement/productionCosting/index.vue
+++ b/src/views/productionManagement/productionCosting/index.vue
@@ -1,177 +1,310 @@
 <template>
 	<div class="app-container">
-		<div class="search_form">
-			<div>
-				<span class="search_title">鐢熶骇鏃ユ湡锛�</span>
-				<el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
-												placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
-				<span class="search_title ml10">鐢熶骇浜猴細</span>
-				<el-input
-					v-model="searchForm.schedulingUserName"
-					style="width: 240px"
-					placeholder="璇疯緭鍏�"
-					@change="handleQuery"
-					clearable
-					prefix-icon="Search"
-				/>
-				<span class="search_title ml10">鍚堝悓鍙凤細</span>
-				<el-input
-					v-model="searchForm.salesContractNo"
-					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>
+			<el-row :gutter="16" class="content-row">
+				<!-- 宸︿晶鍙拌处 + 椤堕儴绛涢�� -->
+				<el-col :xs="24" :sm="24" :md="24" :lg="8" :xl="8" class="left-col">
+					<div class="left-panel">
+						<div class="left-header">
+							<el-form :model="searchForm" inline>
+								<el-form-item prop="dateType">
+									<el-radio-group v-model="searchForm.dateType" size="small" @change="handleDateTypeChange">
+										<el-radio-button label="day">鏃�</el-radio-button>
+										<el-radio-button label="month">鏈�</el-radio-button>
+									</el-radio-group>
+								</el-form-item>
+								
+								<el-form-item label="鏃ユ湡锛�" prop="dateRange">
+									<el-date-picker
+										v-model="searchForm.dateRange"
+										:type="searchForm.dateType === 'day' ? 'date' : 'daterange'"
+										range-separator="鑷�"
+										start-placeholder="寮�濮嬫棩鏈�"
+										end-placeholder="缁撴潫鏃ユ湡"
+										format="YYYY-MM-DD"
+										value-format="YYYY-MM-DD"
+										style="width: 200px"
+										@change="handleDateRangeChange"
+									/>
+								</el-form-item>
+							</el-form>
+						</div>
+						<PIMTable
+							rowKey="id"
+							:column="leftTableColumn"
+							:tableData="leftTableData"
+							:tableLoading="tableLoading"
+							:page="page"
+							@row-click="handleLeftRowClick"
+							@pagination="pagination"
+						></PIMTable>
+					</div>
+				</el-col>
+				
+				<!-- 鍙充晶鏄庣粏 -->
+				<el-col :xs="24" :sm="24" :md="24" :lg="16" :xl="16" class="right-col">
+					<div class="right-panel">
+						
+						<el-form inline>
+							<el-form-item>
+								<el-button type="primary" @click="handleOut">瀵煎嚭</el-button>
+							</el-form-item>
+						</el-form>
+						<PIMTable
+							rowKey="id"
+							:column="tableColumn"
+							:tableData="tableData"
+							:page="page1"
+							:tableLoading="tableLoading1"
+							style="margin-right: 20px;"
+							@pagination="pagination1"
+						></PIMTable>
+					</div>
+				</el-col>
+			</el-row>
 		</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";
-import {productionAccountingListPage} from "@/api/productionManagement/productionCosting.js";
+import {salesLedgerProductionAccountingListProductionDetails, salesLedgerProductionAccountingList} from "@/api/productionManagement/productionCosting.js";
 const { proxy } = getCurrentInstance();
 
 const tableColumn = ref([
 	{
 		label: "鐢熶骇鏃ユ湡",
 		prop: "schedulingDate",
-		width: 120,
+    minWidth: 100,
 	},
 	{
 		label: "鐢熶骇浜�",
 		prop: "schedulingUserName",
-		width: 90,
+    minWidth: 100,
 	},
 	{
 		label: "鍚堝悓鍙�",
 		prop: "salesContractNo",
-		width: 220,
+    minWidth: 100,
 	},
-	// {
-	// 	label: "瀹㈡埛鍚堝悓鍙�",
-	// 	prop: "customerContractNo",
-	// 	width: 250,
-	// },
 	{
 		label: "瀹㈡埛鍚嶇О",
 		prop: "customerName",
-		width: 250,
+    minWidth: 100,
 	},
-	// {
-	// 	label: "椤圭洰鍚嶇О",
-	// 	prop: "projectName",
-	// 	width:300
-	// },
 	{
 		label: "浜у搧澶х被",
-		prop: "productCategory",
-		width: 160,
+		prop: "productName",
+    minWidth: 100,
 	},
 	{
 		label: "瑙勬牸鍨嬪彿",
-		prop: "specificationModel",
-		width: 160,
+		prop: "productModelName",
+    minWidth: 100,
 	},
 	{
 		label: "鍗曚綅",
 		prop: "unit",
+    minWidth: 100,
 	},
 	{
 		label: "宸ュ簭",
 		prop: "process",
+    minWidth: 100,
 	},
 	{
 		label: "鐢熶骇鏁伴噺",
-		prop: "finishedNum",
-		width: 100,
+		prop: "quantity",
+    minWidth: 100,
 	},
 	{
 		label: "宸ユ椂瀹氶",
 		prop: "workHours",
-		width: 100,
+    minWidth: 100,
 	},
 	{
 		label: "宸ヨ祫",
 		prop: "wages",
-		width: 100,
+    minWidth: 100,
 	},
 ]);
+
+// 宸︿晶姹囨�诲彴璐﹀垪锛堢敓浜т汉銆佷骇閲忋�佸伐璧勩�佸悎鏍肩巼锛�
+const leftTableColumn = ref([
+	{
+		label: "鐢熶骇浜�",
+		prop: "schedulingUserName",
+    minWidth: 100,
+	},
+	{
+		label: "浜ч噺",
+		prop: "outputNum",
+    minWidth: 100,
+
+  },
+	{
+		label: "宸ヨ祫",
+		prop: "wages",
+    minWidth: 100,
+
+	},
+	{
+		label: "鍚堟牸鐜�",
+		prop: "outputRate",
+    minWidth: 100,
+    formatData: (val) => {
+      if (val == null || val === '') return '-'
+      return parseFloat(val).toFixed(2)
+    },
+	},
+]);
+
 const tableData = ref([]);
 const tableLoading = ref(false);
+const tableLoading1 = ref(false);
+const leftTableData = ref([]);
+// 鏃� / 鏈� 鍒囨崲锛堥粯璁ゆ寜鏃ワ級
 const page = reactive({
 	current: 1,
 	size: 100,
 	total: 0,
 });
 
+const page1 = reactive({
+  current: 1,
+  size: 100,
+  total: 0,
+});
+
 const data = reactive({
 	searchForm: {
 		schedulingUserName: "",
 		salesContractNo: "",
-		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"),
+    dateType: "day",
+    dateRange: dayjs().format("YYYY-MM-DD"),
+		entryDate: dayjs().format("YYYY-MM-DD"),
+		entryDateStart: undefined,
+		entryDateEnd: undefined,
 	},
 });
 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) => {
+
+const pagination1 = (obj) => {
+  page1.current = obj.page;
+  page1.size = obj.limit;
+	getList1();
+};
+
+const handleDateRangeChange = (value) => {
 	if (value) {
-		searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
-		searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
+    if (searchForm.value.dateType === "day") {
+      searchForm.value.entryDate = value;
+    } else {
+      searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
+      searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
+    }
+
 	} else {
+		searchForm.value.entryDate = undefined;
 		searchForm.value.entryDateStart = undefined;
 		searchForm.value.entryDateEnd = undefined;
 	}
-	handleQuery();
+  reloadData()
 };
+
 const getList = () => {
 	tableLoading.value = true;
 	const params = { ...searchForm.value, ...page };
-	params.entryDate = undefined
-	productionAccountingListPage(params).then((res) => {
-		tableLoading.value = false;
-		tableData.value = res.data.records;
-		page.total = res.data.total;
-	});
+
+  salesLedgerProductionAccountingList(params).then((res) => {
+		const records = res.data.records || [];
+    leftTableData.value = records;
+		page.total = res.data.total || 0;
+	}).finally(() => {
+    tableLoading.value = false;
+  })
+
+
+
 };
+
+const getList1 = () => {
+  tableLoading1.value = true;
+  const params = { ...page1, ...searchForm.value };
+  salesLedgerProductionAccountingListProductionDetails(params).then((res) => {
+    tableData.value = res.data.records || [];;
+    page1.total = res.data.total || 0;
+  }).finally(() => {
+    tableLoading1.value = false;
+  })
+};
+
+// 鏋勫缓宸︿晶姹囨�诲彴璐︼紙鎸夌敓浜т汉姹囨�讳骇閲忋�佸伐璧勭瓑锛�
+const buildLeftTableData = (records) => {
+	const map = {};
+	records.forEach((item) => {
+		const key = item.schedulingUserName || "鏈煡";
+		if (!map[key]) {
+			map[key] = {
+				id: key,
+				schedulingUserName: key,
+				finishedNum: 0,
+				wages: 0,
+				qualifiedRate: item.qualifiedRate ?? null,
+			};
+		}
+		map[key].finishedNum += Number(item.finishedNum || 0);
+		map[key].wages += Number(item.wages || 0);
+		if (item.qualifiedRate != null) {
+			map[key].qualifiedRate = item.qualifiedRate;
+		}
+	});
+	leftTableData.value = Object.values(map);
+};
+
+// 宸︿晶鏃�/鏈堝垏鎹�
+const handleDateTypeChange = (value) => {
+	// 杩欓噷鍙綔涓虹瓫閫夋潯浠剁殑涓�閮ㄥ垎锛岀洿鎺ラ噸鏂版煡璇㈠垪琛�
+  if (value === "day") {
+    searchForm.value.entryDate = dayjs().format("YYYY-MM-DD");
+    searchForm.value.dateRange = searchForm.value.entryDate
+  } else {
+    searchForm.value.entryDateStart = dayjs().startOf("month").format("YYYY-MM-DD");
+    searchForm.value.entryDateEnd = dayjs().endOf("month").format("YYYY-MM-DD");
+    searchForm.value.dateRange = [searchForm.value.entryDateStart, searchForm.value.entryDateEnd]
+  }
+
+  reloadData()
+};
+
+const reloadData = () => {
+  page.current = 1;
+  page1.current = 1;
+  getList();
+  tableData.value = []
+}
+
+// 鐐瑰嚮宸︿晶琛岋紝鍒峰彸渚ф槑缁嗭紙鎸夌敓浜т汉杩囨护锛�
+const handleLeftRowClick = (row) => {
+	searchForm.value.schedulingUserName = row.schedulingUserName || "";
+	handleQuery();
+};
+
+// 鏌ヨ鍒楄〃
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+const handleQuery = () => {
+  page1.current = 1;
+  getList1();
+};
+
 
 // 瀵煎嚭
 const handleOut = () => {
@@ -181,7 +314,7 @@
 		type: "warning",
 	})
 		.then(() => {
-			proxy.download("/basic/customer/export", {}, "鐢熶骇鏍哥畻.xlsx");
+			proxy.download("/salesLedger/productionAccounting/export", {}, "鐢熶骇鏍哥畻.xlsx");
 		})
 		.catch(() => {
 			proxy.$modal.msg("宸插彇娑�");
@@ -193,4 +326,48 @@
 });
 </script>
 
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+.content-row {
+  width: 100%;
+}
+
+.content-row .left-col,
+.content-row .right-col {
+  margin-bottom: 16px;
+}
+
+.left-panel,
+.right-panel {
+  display: flex;
+  flex-direction: column;
+  gap: 10px;
+  min-width: 0;
+}
+
+.left-header {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+}
+
+.left-title {
+  font-size: 16px;
+  color: #ffffff;
+}
+
+.header-filters {
+  display: flex;
+  align-items: center;
+  flex: 1;
+  justify-content: flex-end;
+  gap: 8px;
+}
+
+.search_title {
+  color: #ffffff;
+}
+
+.ml10 {
+  margin-left: 10px;
+}
+</style>

--
Gitblit v1.9.3