From 66a61e5084be68c8f7aa72f28607ef7d1664fb06 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期三, 06 五月 2026 14:41:12 +0800
Subject: [PATCH] 生产核算模块开发
---
src/pages.json | 14
src/pages/productionManagement/productionAccounting/index.vue | 498 +++++++++++++++++++++++++++++++++++++++++++++++++
src/pages/works.vue | 20 -
src/api/productionManagement/productionCosting.js | 18 +
4 files changed, 531 insertions(+), 19 deletions(-)
diff --git a/src/api/productionManagement/productionCosting.js b/src/api/productionManagement/productionCosting.js
index 8cc0251..ed969f6 100644
--- a/src/api/productionManagement/productionCosting.js
+++ b/src/api/productionManagement/productionCosting.js
@@ -8,4 +8,22 @@
method: "get",
params: query,
});
+}
+
+// 宸﹁竟琛ㄦ牸鐨勬帴鍙� (姹囨��)
+export function salesLedgerProductionAccountingList(query) {
+ return request({
+ url: "/productionAccount/listPage",
+ method: "get",
+ params: query,
+ });
+}
+
+// 鍙宠竟琛ㄦ牸鐨勬帴鍙� (鏄庣粏)
+export function salesLedgerProductionAccountingListProductionDetails(query) {
+ return request({
+ url: "/productionAccount/listProductionDetails",
+ method: "get",
+ params: query,
+ });
}
\ No newline at end of file
diff --git a/src/pages.json b/src/pages.json
index ee0b3e0..55521e4 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -858,13 +858,13 @@
"navigationStyle": "custom"
}
},
- // {
- // "path": "pages/productionManagement/productionCosting/index",
- // "style": {
- // "navigationBarTitleText": "鐢熶骇鏍哥畻",
- // "navigationStyle": "custom"
- // }
- // },
+ {
+ "path": "pages/productionManagement/productionAccounting/index",
+ "style": {
+ "navigationBarTitleText": "鐢熶骇鏍哥畻",
+ "navigationStyle": "custom"
+ }
+ },
{
"path": "pages/inventoryManagement/receiptManagement/index",
"style": {
diff --git a/src/pages/productionManagement/productionAccounting/index.vue b/src/pages/productionManagement/productionAccounting/index.vue
new file mode 100644
index 0000000..b20b407
--- /dev/null
+++ b/src/pages/productionManagement/productionAccounting/index.vue
@@ -0,0 +1,498 @@
+<template>
+ <view class="production-accounting">
+ <PageHeader title="鐢熶骇鏍哥畻"
+ @back="goBack" />
+
+ <!-- 绛涢�夊尯鍩� -->
+ <view class="filter-section">
+ <view class="date-type-selector">
+ <up-tabs :list="dateTypeList"
+ :current="currentDateTypeIndex"
+ @change="handleDateTypeChange"
+ :activeStyle="{ color: '#2979ff', fontWeight: 'bold' }"
+ lineWidth="30"
+ lineHeight="3" />
+ </view>
+
+ <view class="date-picker-bar"
+ @click="showDatePicker = true">
+ <view class="date-display">
+ <up-icon name="calendar"
+ size="20"
+ color="#2979ff"></up-icon>
+ <text class="date-text">{{ dateDisplayText }}</text>
+ </view>
+ <up-icon name="arrow-right"
+ size="16"
+ color="#999"></up-icon>
+ </view>
+ </view>
+
+ <!-- 姹囨�诲垪琛� -->
+ <view class="summary-section"
+ v-if="!showDetail">
+ <view class="section-header">
+ <text class="section-title">鐢熶骇浜哄憳姹囨��</text>
+ </view>
+ <view class="ledger-list"
+ v-if="summaryList.length > 0">
+ <view v-for="(item, index) in summaryList"
+ :key="index"
+ class="ledger-item"
+ @click="handleRowClick(item)">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="user-icon">
+ <up-icon name="account"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.schedulingUserName || '鏈煡' }}</text>
+ </view>
+ <view class="item-right">
+ <up-icon name="arrow-right"
+ size="16"
+ color="#999"></up-icon>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-grid">
+ <view class="grid-item">
+ <text class="grid-label">浜ч噺</text>
+ <text class="grid-value">{{ item.finishedNum || 0 }}</text>
+ </view>
+ <view class="grid-item">
+ <text class="grid-label">宸ヨ祫</text>
+ <text class="grid-value highlight">楼{{ item.wages || 0 }}</text>
+ </view>
+ <view class="grid-item">
+ <text class="grid-label">鍚堟牸鐜�</text>
+ <text class="grid-value">{{ formatOutputRate(item.outputRate) }}</text>
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <up-empty mode="data"
+ text="鏆傛棤姹囨�绘暟鎹�" />
+ </view>
+ </view>
+
+ <!-- 鏄庣粏鍒楄〃 (鐐瑰嚮姹囨�昏鍚庢樉绀�) -->
+ <view class="detail-section"
+ v-else>
+ <view class="section-header back-bar"
+ @click="showDetail = false">
+ <up-icon name="arrow-left"
+ size="16"
+ color="#2979ff"></up-icon>
+ <text class="back-text">杩斿洖姹囨�� ({{ currentUserName }})</text>
+ </view>
+
+ <view class="ledger-list"
+ v-if="detailList.length > 0">
+ <view v-for="(item, index) in detailList"
+ :key="index"
+ class="ledger-item no-click">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="product-icon">
+ <up-icon name="shopping-cart"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.productName }}</text>
+ </view>
+ <view class="item-tag">
+ <text class="tag-text">{{ item.schedulingDate }}</text>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">瑙勬牸鍨嬪彿</text>
+ <text class="detail-value">{{ item.productModelName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">宸ュ簭</text>
+ <text class="detail-value">{{ item.process }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鐢熶骇鏁伴噺</text>
+ <text class="detail-value">{{ item.quantity }} {{ item.unit }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">宸ユ椂瀹氶</text>
+ <text class="detail-value">{{ item.workHours }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">宸ヨ祫</text>
+ <text class="detail-value highlight">楼{{ item.wages }}</text>
+ </view>
+ </view>
+ </view>
+ <up-loadmore :status="loadStatus"
+ @loadmore="getDetailList" />
+ </view>
+ <view v-else
+ class="no-data">
+ <up-empty mode="data"
+ text="鏆傛棤鏄庣粏鏁版嵁" />
+ </view>
+ </view>
+
+ <!-- 鏃ユ湡閫夋嫨鍣� -->
+ <up-datetime-picker :show="showDatePicker"
+ v-model="pickerValue"
+ :mode="currentDateType === 'day' ? 'date' : 'year-month'"
+ @confirm="handleDateConfirm"
+ @cancel="showDatePicker = false" />
+ </view>
+</template>
+
+<script setup>
+ import { ref, reactive, computed, onMounted } from "vue";
+ import {
+ salesLedgerProductionAccountingList,
+ salesLedgerProductionAccountingListProductionDetails,
+ } from "@/api/productionManagement/productionCosting";
+ import PageHeader from "@/components/PageHeader.vue";
+ import dayjs from "dayjs";
+
+ // 绛涢�夌浉鍏�
+ const dateTypeList = [{ name: "鏃�" }, { name: "鏈�" }];
+ const currentDateTypeIndex = ref(0);
+ const currentDateType = computed(() =>
+ currentDateTypeIndex.value === 0 ? "day" : "month"
+ );
+ const showDatePicker = ref(false);
+ const pickerValue = ref(Date.now());
+ const selectedDate = ref(dayjs().format("YYYY-MM-DD"));
+
+ const dateDisplayText = computed(() => {
+ return currentDateType.value === "day"
+ ? selectedDate.value
+ : dayjs(selectedDate.value).format("YYYY-MM");
+ });
+
+ // 鏁版嵁鐩稿叧
+ const summaryList = ref([]);
+ const detailList = ref([]);
+ const showDetail = ref(false);
+ const currentUserName = ref("");
+ const loadStatus = ref("loadmore");
+
+ const page = reactive({
+ current: 1,
+ size: 20,
+ total: 0,
+ });
+
+ const page1 = reactive({
+ current: 1,
+ size: 20,
+ total: 0,
+ });
+
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+
+ // 鍒囨崲鏃ユ湡绫诲瀷
+ const handleDateTypeChange = index => {
+ currentDateTypeIndex.value = index.index;
+ if (currentDateType.value === "day") {
+ selectedDate.value = dayjs().format("YYYY-MM-DD");
+ } else {
+ selectedDate.value = dayjs().startOf("month").format("YYYY-MM-DD");
+ }
+ reloadData();
+ };
+
+ // 纭鏃ユ湡閫夋嫨
+ const handleDateConfirm = e => {
+ selectedDate.value = dayjs(e.value).format("YYYY-MM-DD");
+ showDatePicker.value = false;
+ reloadData();
+ };
+
+ // 鏍煎紡鍖栧悎鏍肩巼
+ const formatOutputRate = val => {
+ if (val == null || val === "") return "-";
+ return parseFloat(val).toFixed(2) + "%";
+ };
+
+ // 鍔犺浇姹囨�诲垪琛�
+ const getSummaryList = () => {
+ uni.showLoading({ title: "鍔犺浇涓�..." });
+ const params = {
+ dateType: currentDateType.value,
+ entryDate: currentDateType.value === "day" ? selectedDate.value : undefined,
+ entryDateStart:
+ currentDateType.value === "month"
+ ? dayjs(selectedDate.value).startOf("month").format("YYYY-MM-DD")
+ : undefined,
+ entryDateEnd:
+ currentDateType.value === "month"
+ ? dayjs(selectedDate.value).endOf("month").format("YYYY-MM-DD")
+ : undefined,
+ pageNum: page.current,
+ pageSize: page.size,
+ };
+
+ salesLedgerProductionAccountingList(params)
+ .then(res => {
+ summaryList.value = res.data.records || [];
+ page.total = res.data.total || 0;
+ })
+ .finally(() => {
+ uni.hideLoading();
+ });
+ };
+
+ // 鍔犺浇鏄庣粏鍒楄〃
+ const getDetailList = (isLoadMore = false) => {
+ if (!isLoadMore) {
+ page1.current = 1;
+ detailList.value = [];
+ }
+ loadStatus.value = "loading";
+
+ const params = {
+ schedulingUserName: currentUserName.value,
+ dateType: currentDateType.value,
+ entryDate: currentDateType.value === "day" ? selectedDate.value : undefined,
+ entryDateStart:
+ currentDateType.value === "month"
+ ? dayjs(selectedDate.value).startOf("month").format("YYYY-MM-DD")
+ : undefined,
+ entryDateEnd:
+ currentDateType.value === "month"
+ ? dayjs(selectedDate.value).endOf("month").format("YYYY-MM-DD")
+ : undefined,
+ pageNum: page1.current,
+ pageSize: page1.size,
+ };
+
+ salesLedgerProductionAccountingListProductionDetails(params)
+ .then(res => {
+ const records = res.data.records || [];
+ detailList.value = isLoadMore ? [...detailList.value, ...records] : records;
+ page1.total = res.data.total || 0;
+
+ if (detailList.value.length >= page1.total) {
+ loadStatus.value = "nomore";
+ } else {
+ loadStatus.value = "loadmore";
+ page1.current++;
+ }
+ })
+ .catch(() => {
+ loadStatus.value = "loadmore";
+ });
+ };
+
+ // 鐐瑰嚮姹囨�昏
+ const handleRowClick = item => {
+ currentUserName.value = item.schedulingUserName;
+ showDetail.value = true;
+ getDetailList();
+ };
+
+ // 閲嶆柊鍔犺浇鏁版嵁
+ const reloadData = () => {
+ page.current = 1;
+ showDetail.value = false;
+ getSummaryList();
+ };
+
+ onMounted(() => {
+ getSummaryList();
+ });
+</script>
+
+<style scoped lang="scss">
+ .production-accounting {
+ background-color: #f5f7fa;
+ min-height: 100vh;
+ padding-bottom: 30rpx;
+
+ .filter-section {
+ background-color: #ffffff;
+ padding: 20rpx 30rpx;
+ margin-bottom: 20rpx;
+
+ .date-type-selector {
+ margin-bottom: 20rpx;
+ }
+
+ .date-picker-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ background-color: #f0f4ff;
+ padding: 16rpx 24rpx;
+ border-radius: 8rpx;
+
+ .date-display {
+ display: flex;
+ align-items: center;
+ gap: 12rpx;
+
+ .date-text {
+ font-size: 28rpx;
+ color: #2979ff;
+ font-weight: bold;
+ }
+ }
+ }
+ }
+
+ .section-header {
+ padding: 20rpx 30rpx;
+
+ .section-title {
+ font-size: 30rpx;
+ font-weight: bold;
+ color: #333;
+ border-left: 8rpx solid #2979ff;
+ padding-left: 16rpx;
+ }
+
+ &.back-bar {
+ display: flex;
+ align-items: center;
+ gap: 10rpx;
+ background-color: #ffffff;
+ margin-bottom: 20rpx;
+
+ .back-text {
+ font-size: 28rpx;
+ color: #2979ff;
+ }
+ }
+ }
+
+ .ledger-list {
+ padding: 0 20rpx;
+
+ .ledger-item {
+ background-color: #ffffff;
+ border-radius: 16rpx;
+ padding: 24rpx;
+ margin-bottom: 20rpx;
+ box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
+
+ &:active {
+ background-color: #f9f9f9;
+ }
+
+ &.no-click:active {
+ background-color: #ffffff;
+ }
+
+ .item-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 16rpx;
+
+ .item-left {
+ display: flex;
+ align-items: center;
+ gap: 12rpx;
+
+ .user-icon,
+ .product-icon {
+ width: 48rpx;
+ height: 48rpx;
+ background: linear-gradient(135deg, #2979ff, #64a1ff);
+ border-radius: 8rpx;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ .item-id {
+ font-size: 28rpx;
+ font-weight: bold;
+ color: #333;
+ }
+ }
+
+ .item-tag {
+ background-color: #f0f4ff;
+ padding: 4rpx 12rpx;
+ border-radius: 4rpx;
+
+ .tag-text {
+ font-size: 24rpx;
+ color: #2979ff;
+ }
+ }
+ }
+
+ .item-details {
+ padding-top: 10rpx;
+
+ .detail-grid {
+ display: flex;
+ justify-content: space-between;
+
+ .grid-item {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ flex: 1;
+
+ .grid-label {
+ font-size: 24rpx;
+ color: #999;
+ margin-bottom: 8rpx;
+ }
+
+ .grid-value {
+ font-size: 28rpx;
+ color: #333;
+ font-weight: 500;
+
+ &.highlight {
+ color: #ff5a5f;
+ }
+ }
+ }
+ }
+
+ .detail-row {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 12rpx;
+
+ .detail-label {
+ font-size: 26rpx;
+ color: #999;
+ }
+
+ .detail-value {
+ font-size: 26rpx;
+ color: #333;
+
+ &.highlight {
+ color: #ff5a5f;
+ font-weight: bold;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ .no-data {
+ padding-top: 100rpx;
+ }
+ }
+</style>
diff --git a/src/pages/works.vue b/src/pages/works.vue
index a647ada..04aeb3c 100644
--- a/src/pages/works.vue
+++ b/src/pages/works.vue
@@ -570,7 +570,7 @@
// 鐢熶骇绠℃帶鍔熻兘鏁版嵁
const productionItems = reactive([
{
- icon: "/static/images/icon/shengchanbaogong.svg",
+ icon: "/static/images/icon/shengchanbaogong1.svg",
label: "鐢熶骇璁㈠崟",
},
// {
@@ -578,11 +578,11 @@
// label: "鐢熶骇娲惧伐",
// },
{
- icon: "/static/images/icon/shengchanbaogong.svg",
+ icon: "/static/images/icon/shengchanbaogong1.svg",
label: "鐢熶骇鎺掍骇",
},
{
- icon: "/static/images/icon/shengchanbaogong.svg",
+ icon: "/static/images/icon/shengchanbaogong1.svg",
label: "涓荤敓浜ц鍒�",
},
{
@@ -590,17 +590,13 @@
label: "鐢熶骇鎶ュ伐",
},
{
- icon: "/static/images/icon/xiaoshoutaizhang.svg",
+ icon: "/static/images/icon/shengchanbaogong1.svg",
label: "鎶ュ伐鍙拌处",
},
- // {
- // icon: "/static/images/icon/shengchanbaogong.svg",
- // label: "鐢熶骇宸ュ崟",
- // },
- // {
- // icon: "/static/images/icon/shengchanhesuan@2x.svg",
- // label: "鐢熶骇鏍哥畻",
- // },
+ {
+ icon: "/static/images/icon/shengchanbaogong1.svg",
+ label: "鐢熶骇鏍哥畻",
+ },
]);
// 璁惧绠$悊鍔熻兘鏁版嵁
--
Gitblit v1.9.3